处理 Class 导致属性在创建新对象时被覆盖

Handle Class causing properties to be overwritten when create new object

看看下面的最小工作示例,
ClassA.m

classdef ClassA < handle
    properties
        h1 = 0;
        h2 = 0;
    end
    methods
        function obj = ClassA(n1,n2)
            if nargin == 2
                obj.h1 = n1;
                obj.h2 = n2;
            end
        end
    end
end

ClassB.m

classdef ClassB < handle
    properties
        a  = ClassA;
        a0 = ClassA;
    end
    methods
        function obj = ClassB(n1,n2)
            if nargin == 2 
                obj.a.h1 = n1.h1;
                obj.a.h2 = n1.h2;
                
                obj.a0.h1 = n2.h1;
                obj.a0.h2 = n2.h2;
            end
        end
    end
end

main.m

h1 = ClassA(1,1);
h2 = ClassA(2,2);
h3 = ClassA(3,3);
h4 = ClassA(4,4);

x01 = ClassB(h1,h2);
x01.a.h1
x01.a.h2

x12 = ClassB(h3,h4);
x01.a.h1 % should keep its value as 1
x01.a.h2 % should keep its value as 2

当我实例化 class B 的第二个对象导致 x01 被覆盖时出现问题。我认为这与句柄 class 有关。有什么聪明的方法可以避免这个问题吗?注意 ClassA 必须被处理,因为我需要修改它的属性。

注意 the documentation 中描述的内容(强调我的):

There are two basic approaches to initializing property values:

  • In the property definition — MATLAB evaluates the expression only once and assigns the same value to the property of every instance.
  • In a class constructor — MATLAB evaluates the assignment expression for each instance, which ensures that each instance has a unique value.

这意味着,对于 class Ba = ClassA 只计算一次,然后 class 创建的每个对象都会得到 [=13] 的副本=].但是因为 ClassA 是句柄对象,所以所有对象最终都指向同一个对象(复制的是句柄,而不是对象)。

因此,解决方案是按照第二种方法初始化 属性 值:在 class 构造函数中:

classdef ClassB < handle
    properties
        a;
        a0;
    end
    methods
        function obj = ClassB(n1,n2)
            obj.a  = ClassA;
            obj.a0 = ClassA;
            if nargin == 2 
                obj.a.h1 = n1.h1;
                obj.a.h2 = n1.h2;
                
                obj.a0.h1 = n2.h1;
                obj.a0.h2 = n2.h2;
            end
        end
    end
end