Suppose I have the following class:
classdef myClass < handle
properties
A = 1
end
methods
function obj = myClass(val)
Since you are working with a handle class, both q
and w
in your example refer to the same object in memory; they are themselves a "pointer"/"reference" to the object they represent.
So continuing your example, if you make changes to one, it will be reflected in the other.
>> q = myClass(10);
>> w = q;
>> q.A = 99;
>> disp(w.A)
99
Also note that you are not creating another instance of the class when you call w = q;
. Compare the following examples in terms of memory space:
>> q = myClass(rand(7000));
>> m = memory; disp(m.MemUsedMATLAB)
792870912
>> w = q;
>> m = memory; disp(m.MemUsedMATLAB)
792834048
Against:
>> q = myClass(rand(7000));
>> w = myClass(rand(7000));
??? Error using ==> rand
Out of memory. Type HELP MEMORY for your options.
Playing around with this, I came up with the following hackish solution.
First we create a wrapper function around the class constructor. It creates an object as usual, plus it returns a function handle that acts as a read-only accessor to a closure variable synced with the original object property using a "PostSet" events listener.
The only change to the original class is to add the SetObservable
property attribute:
classdef myClass < handle
properties (SetObservable)
A
end
methods
function obj = myClass(val)
obj.A = val;
end
end
end
function [w A] = myClassWrapper(varargin)
w = myClass(varargin{:});
A = @getWA;
%# closure variable
a = w.A;
%# add listener to when w.A changes
addlistener(w, 'A', 'PostSet',@changeCallback);
function val = getWA()
%# return the value of the closure variable
val = a;
end
function changeCallback(obj,ev)
%# update the closure variable
a = ev.AffectedObject.A;
%#fprintf('Value Changed to %g\n',a)
end
end
Now we can use the wrapper as:
>> [w a] = myClassWrapper(10);
>> a()
ans =
10
>> w.A = 99;
>> a()
ans =
99