Home > Software design >  Handle Class causing properties to be overwritten when create new object
Handle Class causing properties to be overwritten when create new object

Time:02-02

Take a look at the following minimal working example,
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

The problem occurs when I instantiate a second object of class B which causing x01 to be overwritten. I think this has to do with handle class. Is there any clever way to avoid this problem? Notice ClassA must be handle since I need to modify its properties.

CodePudding user response:

Note what is described in the documentation (emphasis mine):

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.

This means that, for class B, a = ClassA is evaluated only once, and then every object of that class created gets a copy of a. But because ClassA is a handle object, all objects end up pointing to the same object (it is the handle that is copied, not the object).

So, the solution is follow the 2nd method to initialize property values: in the class constructor:

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
  •  Tags:  
  • Related