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

2 次查看(过去 30 天)
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?

回答(1 个)

per isakson
per isakson 2022-5-27
编辑:per isakson 2022-5-28
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
  1 个评论
Dominic Diston
Dominic Diston 2022-11-22
Thanks for the explanation and sorry for the delay in responded (I caught COVID and took a long time to recover fully).
I certainly didn't expect this to be a problem as the code apparently states what needs to happen. I categorize this as a "gotcha". It was difficult to isolate and identify. Obviously we should be doing things properly and be using constructors. More generally, MATLAB should allow us to do things in the way in which I originally did them.
This has really shaken my confidence in MATLAB. I now need to go through everything I have and see if the same feature exists anywhere. What a pain!!

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 MATLAB Mobile Fundamentals 的更多信息

产品


版本

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by