2011-06-23 68 views
15

有没有办法在MATLAB类中定义静态成员变量?如何在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 
+1

这并不意味着它AFAIK,但[持久](http://www.mathworks.com/help/techdoc/ref/persistent.html)工作? –

+1

是的,我在静态成员函数中获得了一个带有持久变量的解决方法。 – Vahagn

+1

您应该将其作为对此问题感兴趣的其他人的回答 –

回答

15

你不能,它是由设计。你应该使用一个变量(在2011年应用于1980年的MATLAB技术)!

为了完整起见,我应该提到,实际上2010年有一个没有记录的,可能不再支持static属性修饰符。

有关背景看hereDave Foti答案,MATLAB OO组经理:

在MATLAB中,类可以定义常量 性质,但在其他 语言,如C的感觉不是“静” 性质++ 。有测试 版本,试验 “静态”属性和 未记录的属性仍然从 然后。但是,在未来的 MATLAB版本中,静态属性 未被记录,不应使用,并且 可能会被删除。 R2008a将其实现为 作为常量的同义词,并且提供 超越 的常规 属性的已记录行为。

不变属性可能不会改变 从 中指定的初始值属性声明。有几个原因是为什么MATLAB的工作原理是 。首先,MATLAB具有 长期规则,变量 总是优先于函数和类的名称 , 赋值语句引入 变量(如果尚不存在)。因此,“A.B = C”形式的任何表达式都将引入一个新变量A,该变量是一个结构数组,其中包含一个值为C的字段B的 。B = C” 可以指 类A的静态属性,那么类A采取 先例在变量A和这 将是一个非常显著 不相容与以前版本的MATLAB ,这将意味着一个 米-file含分配 声明“AB = C”也有其 含义由一个名为 MATLAB路径上的某处类的介绍 改变。MATLAB程序员 总是能够依靠赋值语句 引入变量 影子任何其他使用相同的名称。

其次,我们发现静态 数据很少用于其他类 ,除非作为 类中的私人数据或作为公共常量。例如,对几个Java类库的调查发现,所有公共的 静态字段也是最终的。在 MATLAB中,常量属性可以是 ,类似于Java中的“public final static” 字段。对于 类的内部数据,MATLAB已经拥有了持久性 变量,这些变量可以在私有或受保护方法的 内创建,或者 类私下使用的本地函数。 也有很好的理由避免MATLAB中的静态数据,其中 可能。如果某个类具有静态数据,则可能难以在多个应用程序 中使用相同的 类,因为静态数据可能是 应用程序之间的冲突源。在其他一些语言中,这不是一个问题,因为 不同的应用程序分别是 编译成 运行在 可执行文件不同的进程与不同的 类静态数据的副本。在MATLAB中,经常有许多不同的 应用程序可能正在运行在 相同的进程和环境中,并且每个类都有一个 单一副本。

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 
>> 
0

(只是通知) 有(另一个?)的方式来创建MATLAB静态类数据

假设你有一个“处理”类,它的名字是“汽车” 如果你想要的车类具有静态数据,你可以构造另一个手柄类和汽车类抛成分使用,后一类可以作为面向汽车类

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类。

这些代码以“MATLAB 2013b”

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这是不恒定的,可以设置为心的愿望。