MATLAB - 创建变量的引用(句柄?)

Dan*_*hoa 9 oop matlab matlab-class

假设我有以下课程:

classdef myClass < handle
    properties
        A = 1
    end
    methods
        function obj = myClass(val)
            obj.A = val;
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

假设我实例化了这个类的一个实例,然后稍微操作它然后复制它.由于它是一个句柄类,"副本"实际上只是同一个对象的另一个实例:

>> q = myClass(10);
>> q.A = 15;
>> w = q;
>> disp(w.A)
   15
Run Code Online (Sandbox Code Playgroud)

但是我想观察A而不需要实例化myClass.天真地做着

>> value = w.A
Run Code Online (Sandbox Code Playgroud)

不起作用,因为这只是复制价值; w.A后来长宁不会改变value.

有没有办法提供"指针"或"引用"而w.A无需创建单独的句柄类?我宁愿保留符号w.A而不是像w.A.value(我必须创建句柄类来包含该值).

编辑:我正在使用此功能,以帮助封装我的代码,以供我的研究实验室使用.我正在设计MATLAB和Arduino之间的接口来控制空中和地面车辆; 我希望能够访问诸如" vehicle.pwmMax"," vehicle.flightCeiling"之类的东西来封装底层对象:" vehicle.Globals.pwmMax.value"等.

gra*_*tnz 16

您可以使用PropertyReference类来完成此操作

classdef PropertyReference < handle
    %PropertyReference Reference to a property in another object    
    properties
        sourceHandle
        sourceFieldName
    end

    properties (Dependent = true)
         Value
    end

    methods                
        function obj = PropertyReference (source, fieldName)            
            obj.sourceHandle = source;
            obj.sourceFieldName = fieldName
        end
        function value = get.Value( obj )
            value = obj.sourceHandle.(obj.sourceFieldName);
        end

        function set.Value( obj, value )
            obj.sourceHandle.(obj.sourceFieldName) = value;
        end
        function disp( obj )
            disp(obj.Value);
        end
    end              
end
Run Code Online (Sandbox Code Playgroud)

继续您的示例,您可以使用PropertyReference,如下所示:

q = myClass(10);
>> q.A = 15;
>> ref = PropertyReference(q,'A');
>> disp(ref)
   15
>> q.A = 42;
>> disp(ref)
   42
Run Code Online (Sandbox Code Playgroud)

PropertyReference类的使用有点尴尬,但原始类保持不变.

编辑 - 根据strictrude27评论添加了disp函数重载


Ego*_*gon 5

考虑到你的所有约束,我认为没有任何东西可以完全按你的要求完成.

但是,我对你的符号问题并不十分清楚.为什么w.A在考虑value不改变时你想保留符号?保持符号w.A相似并不是一个真正的问题.

使用一些修改过的代码,我可以生成以下执行:

>> q = myClass(10);
>> q.A = 15;
>> w = q;
>> w.A
    15
>> value = w.Aref;
>> value()
    15
>> w.A = 20;
>> value()
ans =
    20
Run Code Online (Sandbox Code Playgroud)

但是没有办法绕过符号,value()因为这是实施的转折点; 我认为是最接近你想要的东西.当您使用以下代码实现时,您将获得上述行为myClass:

classdef myClass < handle
properties
    A = 1;
end
methods
    function obj = myClass(val)
        obj.A = val;
    end
    function a = Aref(obj)
        a =  @()(obj.A);
    end
end
end
Run Code Online (Sandbox Code Playgroud)

所以你看到该Aref方法实际上返回一个函数句柄,它从对象中获取值.这也意味着此引用是只读的!

另请注意,myClass在能够获取值之前,您必须实例化一个实例A(A否则从哪里获取值?).此实例不必在当前工作空间(例如另一个函数范围)内可见,因为myClass实例存储在函数句柄中value.

这种方法的缺点是,你只能得到一个只读的参考,你将不得不使用电话value()来获得实际值,而不是功能句柄(让改变符号,而不是你想保持一个(或至少它可以通过A在我的代码中替换Aval并重命名ArefA)来实现.另一个缺点是解析value可能比简单地解析一个变量慢一点(这是一个问题将取决于你的用法value()).

如果您想要更改某些符号,可以使用依赖属性来完成:

classdef myClass < handle
    properties (Access=private)
        Aval = 1;
    end
    properties (Dependent)
        A;
    end
    methods
        function obj = myClass(val)
            obj.A = val;
        end
        function a = get.A(obj)
            a =  @()(obj.Aval);
        end
        function set.A(obj,value)
            obj.Aval = value;
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

上述的等效执行由下式给出:

>> q = myClass(10);
>> q.A = 15;
>> w = q;
>> w.A()
    15
>> value = w.A;
>> value()
    15
>> w.A = 20;
>> value()
ans =
    20
Run Code Online (Sandbox Code Playgroud)

编辑:我想到了实现这个的另一种方法,这更简单(即只保留原始帖子的类),但它要求你在其他地方更改代码.它背后的基本思想与第一个相同,但没有将它封装在对象本身(这使得对象更清晰,恕我直言).

>> q = myClass(10);
>> q.A = 15;
>> w = q;
>> w.A()
    15
>> value = @()(w.A);
>> value()
    15
>> w.A = 20;
>> value()
ans =
    20
Run Code Online (Sandbox Code Playgroud)