有没有办法在MATLAB类中定义静态成员变量?
这不起作用:
classdef A
properties ( Static )
m = 0;
end
end
建议使用关键字“常量”而不是“静态”,不能修改常量属性。我想要一个类A
的所有对象共有的变量,我希望能够在类A
的方法中修改该变量。
所以我需要的是一个私有静态成员变量。有没有办法在MATLAB中获取它?
在静态成员函数中使用持久变量发现可以解决方法。
在这种情况下,您应该从基类继承所有类,如下所示。
classdef object < handle
properties ( GetAccess = 'public', SetAccess = 'private' )
id
end
methods ( Access = 'protected' )
function obj = object()
obj.id = object.increment();
end
end
methods ( Static, Access = 'private' )
function result = increment()
persistent stamp;
if isempty( stamp )
stamp = 0;
end
stamp = stamp + uint32(1);
result = stamp;
end
end
end
答案 0 :(得分:15)
你不能,这是设计的。您应该使用persistent
变量(2011年应用于1980年的MATLAB技术)!
为了完整性,我应该提一下,实际上2010b是一个未记录的,可能不再受支持的static
属性修饰符。
有关背景,请参阅here MATLAB OO小组经理Dave Foti的答案:
在MATLAB中,类可以定义Constant 属性,但不是“静态” 在其他意义上的属性 像C ++这样的语言。有测试版 试验的版本 “静态”属性和 未记录的属性仍然来自 然后。但是,Static属性是 没有证件,不应该使用,和 很可能在将来被删除 MATLAB发布。 R2008a实现了它 作为Constant的同义词并提供 没有额外的功能 Constant的记录行为 属性。
不能更改常量属性 从中指定的初始值 财产申报。有一个 MATLAB工作的几个原因 它的方式。首先,MATLAB有 长期存在的变量规则 总是先于名字 功能和类和那些 赋值语句介绍一个 变量,如果还不存在。 因此,任何形式的表达“A.B = C“将引入一个新变量A,它是一个包含a的结构数组 字段B,其值为C.如果“A.B = C” 可以引用的静态属性 A级,然后是A级 变量A的先例和这个 会非常重要 与先前版本不兼容 MATLAB。这意味着一个 包含作业的m文件 声明“A.B = C”可以有它的 引言改变了意义 一个名为A的类在某个地方 MATLAB路径。 MATLAB程序员有 总是能够依靠任务 引入变量的语句 影响任何其他相同名称的使用。
其次,我们观察到静电 数据很少在其他类中使用 除了作为私人数据 类或公共常量。对于 例如,几个Java的调查 班级图书馆发现全部公开 静态领域也是最终的。在 MATLAB,常量属性即可 用过“public final static” Java中的字段。对于内部数据 类,MATLAB已经具有持久性 可以在里面创建的变量 私人或受保护的方法或 一个私人使用的本地函数 类。还有很好的理由 避免在MATLAB中的静态数据 可能。如果一个类有静态数据, 它可能很难使用相同的 多个应用程序中的类 因为静态数据可以是一个 的冲突根源 应用。在其他一些语言中, 这不是一个问题,因为 不同的应用是分开的 编译成运行的可执行文件 不同的流程有所不同 类静态数据的副本。在 MATLAB,经常有很多不同 应用程序可能正在运行 同样的过程和环境 每个班级的单一副本。
答案 1 :(得分:11)
这是在Matlab中创建静态属性的直接方法。这个实现和假设(但不可能;参见Mikhail的答案)真正的静态属性之间的唯一区别是设置成员变量的语法。
classdef StaticVarClass
methods (Static = true)
function val = staticVar(newval)
persistent currentval;
if nargin >= 1
currentval = newval;
end
val = currentval;
end
end
end
现在可以通过以下方式读取静态属性staticVar:
StaticVarClass.staticVar
...并通过以下方式设置:
StaticVarClass.staticVar(newval);
因此,例如,这是此功能测试的预期输出:
>> StaticVarClass.staticVar
ans =
[]
>> StaticVarClass.staticVar('foobar')
ans =
foobar
>> StaticVarClass.staticVar
ans =
foobar
>>
此方法适用于您所请求的私有静态属性,但演示代码稍长一些。请注意,这不是句柄类(尽管它在句柄类上也能很好地工作)。
classdef StaticVarClass
methods (Access = private, Static = true)
function val = staticVar(newval)
persistent currentval;
if nargin >= 1
currentval = newval;
end
val = currentval;
end
end
methods
function this = setStatic(this, newval)
StaticVarClass.staticVar(newval);
end
function v = getStatic(this)
v = StaticVarClass.staticVar;
end
end
end
......和测试:
>> x = StaticVarClass
x =
StaticVarClass with no properties.
Methods
>> x.getStatic
ans =
[]
>> x.setStatic('foobar')
ans =
StaticVarClass with no properties.
Methods
>> x.getStatic
ans =
foobar
>>
答案 2 :(得分:1)
(只是告知) 有(另一种?)方法在matlab中创建类似静态的数据
假设你有一个&#34;句柄&#34;它的名字是&#34; car&#34; 如果你想要汽车类有静态数据,你可以构建另一个句柄类并在汽车类投掷组合中使用它,后一个类作为汽车类的静态数据
classdef car<handle
properties
static_data:STATIC_DATA_HOLDER;
end
end
classdef STATIC_DATA_HOLDER<handle
properties
data
end
end
这样,当您创建汽车类的第一个实例时,将创建一个STATIC_DATA_HOLDER实例,当您创建汽车类的第二个实例时,它会使用以前创建的STATIC_DATA_HOLDER类。
这些代码用&#34; MATLAB 2013b&#34;
答案 3 :(得分:0)
获得类似静态属性的另一种解决方法是使用成员变量的初始化代码仅在加载类文件时执行一次的事实。这意味着,如果您有像
这样的定义classdef foo
properties
stuff = some_function()
end
end
然后只调用some_function
一次,如果它返回类类型的对象,则所有实例都将共享它。我添加了一个示例实现,说明了如何使用它:
classdef ClassWithStaticMembers
properties
classvars = StaticVarContainer('foo', 0, 'bar', 2);
othervar
end
methods
function obj=ClassWithStaticMembers(var)
obj.othervar = var;
end
end
end
classdef StaticVarContainer < dynamicprops
methods
function obj=StaticVarContainer(varargin)
for i=1:2:numel(varargin)
obj.addprop(varargin{i});
obj.(varargin{i}) = varargin{i+1};
end
end
end
end
如果您运行此示例代码
obj1 = ClassWithStaticMembers(3);
obj2 = ClassWithStaticMembers(5);
obj1.classvars.foo = [2,3];
obj1.othervar
obj1.classvars
obj2.othervar
obj2.classvars
你会看到,classvars
确实是共享的。我认为这个解决方案比在函数中使用持久变量要好得多,因为你可以根据需要重复使用StaticVarContainer
,它更容易使用,而且,你直接看到属性中静态变量的初始化部分。
要获得结果,OP的问题(即实现对象计数器)需要,可以使共享属性Constant
,以便可以在没有实例的情况下引用它:
classdef ClassWithCounter
properties (Constant)
static = StaticVarContainer('counter', 0);
end
methods
function obj=ClassWithCounter()
obj.static.counter = obj.static.counter + 1;
end
end
end
clear all
obj1 = ClassWithCounter();
obj2 = ClassWithCounter();
obj3 = ClassWithCounter();
ClassWithCounter.static.counter
请注意,Constant
属性仅表示,例如obj1.static
无法更改,但它不会影响obj1.static.counter
,这不是常量,可以设置为内心的愿望。