MATLAB - create reference (handle?) to variable

前端 未结 3 1542
北恋
北恋 2021-02-02 03:13

Suppose I have the following class:

classdef myClass < handle
    properties
        A = 1
    end
    methods
        function obj = myClass(val)
                   


        
3条回答
  •  迷失自我
    2021-02-02 03:40

    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.
    

    EDIT

    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:

    myClass.m

    classdef myClass < handle
        properties (SetObservable)
            A
        end
        methods
            function obj = myClass(val)
                obj.A = val;
            end
        end
    end
    

    myClassWrapper.m

    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
    

提交回复
热议问题