I'm having an issue with a class that has properties that are handle classes. I've created this example to demonstrate the problem:
classdef Problem_Class < handle properties (SetObservable = true) Prop1 end methods function s = Problem_Class s.Prop1 = Prop1_Class; end endendclassdef Prop1_Class < handle properties (SetObservable = true) Prop2 end methods function s = Prop1_Class s.Prop2 = Prop2_Class; end endendclassdef Prop2_Class < handle properties (SetObservable = true) Name (1,:) char end methods function s = Prop2_Class s.Name = ''; end endend
So, If I create an instance of my Problem_Class:
problem = Problem_Class
The issue arises if I now create an array of Prop1, for example:
problem.Prop1.Prop2.Name = 'index 1';problem.Prop1(8).Prop2.Name = 'index 8';problem.Prop1(7).Prop2.Name = 'index 7';
If we look at the .Name property for each problem.Prop1.Prop2, I'd hope to see this:
[problem.Prop1.Prop2]; {ans.Name}'
{'index 1'}
{1×0 char }
{1×0 char }
{1×0 char }
{1×0 char }
{1×0 char }
{'index 7'}
{'index 8'}
But instead I get this:
{'index 1'}
{'index 7'}
{'index 7'}
{'index 7'}
{'index 7'}
{'index 7'}
{'index 7'}
{'index 8'}
The reason this is happening is explained here: https://www.mathworks.com/help/matlab/matlab_oop/initializing-arrays-of-handle-objects.html, where it is stated (at the end) "results in two calls to the class constructor. The first creates the object for array element A(4,5). The second creates a default object that MATLAB copies to all remaining empty array elements."
So, when I call problem.Prop1(8).Prop2.Name = 'index 8'; MATLAB calls the Prop1_Class constructor once, to populate problem.Prop1(8), and then a second time to create a Prop1_Class object that it copies to problem.Prop1(2:7). So now problem.Prop1(2:7) all point to the same object in memory. I don't want this! I need problem.Prop1(2:7) to be unique elements, and I need this to happen implicitly rather than having to pre-initialise the problem.Prop1() array.
I thought I had found the solution here: https://www.mathworks.com/help/matlab/matlab_oop/custom-copy-behavior.html, – I created a class based on the HandleCopy example on that page, and made Problem_Class, Prop1_Class, and Prop2_Class all inherit from that, so that all of them should have the custom copy behaviour. I have verified that, e.g. a = copy(b), where "b" is an instance of the Prop1_Class, then behaves as expected, creating an independent copy of b in a (such that a~=b, but their properties have the same values). However, MATLAB does not appear to call the custom copy method when creating an array!
Going back to the previous example: when I call problem.Prop1(8).Prop2.Name = 'index 8'; once MATLAB has created the problem.Prop1(8) element, and then creates the second Prop1_Class object and "copies" that to problem.Prop1(2:7), how do I get MATLAB to use a custom copy function, so I can prevent all problem.Prop1(2:7) pointing at the same object?
Many thanks for reading this post, all help gratefully received!
Best Answer