Changing the content of an object that is contained with an array of objects

1 view (last 30 days)
Dominic Diston
Dominic Diston on 26 May 2022
Edited: per isakson on 28 May 2022
The following code represents the sort of thing I need to do for an application. This is based on a top-level class called ObjectWithDataContainer.
classdef ObjectWithDataContainer < handle
properties
Data (1,1) DataContainer
end
end
This contains a property called Data whose class is DataContainer, which contains a dataitem called Value (with default set to zero).
classdef DataContainer < handle
properties
Value = 0
end
end
Now, create a vector of ObjectWithDataContainer and verify that both embedded Data values are 0. Then set one of the first Data value to 1 and again verify both Data values.
>> obj(1) = ObjectWithDataContainer ;
>> obj(2) = ObjectWithDataContainer ;
>> obj(1).Data
ans =
DataContainer with properties:
Value: 0
>> obj(2).Data
ans =
DataContainer with properties:
Value: 0
>> obj(1).Data.Value = 1 ;
>> obj(1).Data
ans =
DataContainer with properties:
Value: 1
>> obj(2).Data
ans =
DataContainer with properties:
Value: 1
Although only one Data value has been set, both Data values have been changed to that value.
What on earth is going on here?

Answers (1)

per isakson
per isakson on 27 May 2022
Edited: per isakson on 28 May 2022
The behavior you see is the way Matlab is designed to work. See Properties Containing Objects and Property Default Values. The key message is
"Evaluation of property default values occurs only when the value is first needed, and only once when MATLAB first initializes the class. MATLAB does not reevaluate the expression each time you create an instance of the class."
IMO: When you don't exactly know what you are looking for, these pages aren't that easy to find. And what exactly does "first needed" mean?
In your case the class, DataContainer, is first needed when obj(1) is created. (However, I failed to find that stated in the documentation.) In your objects, obj(1) and obj(2), the values of Data, are handles to the same underlying object of the class, DataContainer.
Anyhow, I replaced
Data (1,1) DataContainer
by
Data (1,1) % DataContainer
and added a contrucctor
function this = ObjectWithDataContainer()
this.Data = DataContainer();
end
Now the code works as you expect.
%%
obj(1) = ObjectWithDataContainer ;
obj(2) = ObjectWithDataContainer ;
%%
obj(1).Data.Value = 1;
obj(2).Data.Value = 2;
%%
obj(1).Data
ans =
DataContainer with properties: Value: 1
obj(2).Data
ans =
DataContainer with properties: Value: 2

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!