Applying method to one object in array affects values of another

I have an array of objects, but when I call a method of one object in the array, the values of other elements of the array change as well.
The code in question is as follows. A 2x2 array of the MixerArray class is initialised. When I call the method add on a(1,1), the values of a(1,2) and a(2,1) change as well. The following code gives an output of 0, 7 even though the add method should only change values of a(1,1)
a(2,2) = MixerArray();
disp(a(1,2).Register_Array.currentVal)
a(1,1).add(3,4);
disp(a(1,2).Register_Array.currentVal)
The class in question is as follows
classdef MixerArray < handle
properties
Register_Array % Array to store values
Length % Number of mixers
end
methods
function obj = MixerArray(n)
if nargin ==0
obj.Register_Array = RegisterArray();
obj.Length = 1;
else
obj.Register_Array = RegisterArray(n);
obj.Length = n;
end
end
% add function
function add(obj, A, B, i)
if nargin == 3
obj.Register_Array.setval(A+B);
else
obj.Register_Array.setval(A+B,i);
end
end
% Update function
function update(obj)
obj.Register_Array.update();
end
end
end
This calls upon a second class
classdef RegisterArray < handle
properties
lastVal % Last value
currentVal % Current value
end
methods
% n is the length of the register
function obj = RegisterArray(n)
if nargin == 0
obj.currentVal = 0;
obj.lastVal = 0;
else
obj.currentVal = zeros(1,n);
obj.lastVal = zeros(1,n);
end
end
% Assignment function
function setval(obj, new_value, i)
if nargin == 2
obj.currentVal = new_value;
else
obj.currentVal(i) = new_value;
end
end
% Update values
function update(obj)
obj.lastVal = obj.currentVal;
end
end
end

 采纳的回答

It is a curious pitfall you've stumbled on. Basically, the solution is to avoid using default empty elements to fill up a MixerArray. Instead, create each element of the array explicitly within the constructor.
a=MixerArray(2,2);
where you would modify the constructor like the following
function obj = MixerArray(varargin)
if ~nargin, return; end
obj(varargin{:})=MixerArray();
for i=1:numel(obj)
obj(i).Register_Array=RegisterArray();
end
end

3 个评论

The reason this is necessary is because your original code
a(2,2) = MixerArray();
forces Matlab to fill a(1,1), a(1,2) and a(2,1) with default empty objects. However, it doesn't create these objects by calling the MixerArray constructor 3 separate times. It calls it only once and copies the resulting object into the 3 missing spots. But because the property Register_Array is a handle object, this copying uses handle copying semantics and therefore for i=1,2,3, every a(i).Register_Array is in fact the same instance.

请先登录,再进行评论。

更多回答(0 个)

类别

在 帮助中心 和 File Exchange 中查找有关 Software Development 的更多信息

产品

版本

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by