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函数重载
考虑到你的所有约束,我认为没有任何东西可以完全按你的要求完成.
但是,我对你的符号问题并不十分清楚.为什么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并重命名Aref为A)来实现.另一个缺点是解析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)