无法在Matlab中更新类定义

时间:2013-06-21 18:42:07

标签: matlab class persistence

我遇到了Matlab的一个令人生气的问题,遗憾的是earlier answer显然同样的问题并没有帮助我。我很抱歉这个问题很长 - 你需要相当多的信息来重现问题(我试图尽可能多地修剪它)。

问题在于:无论我做什么,在使用课程后我都无法“让Matlab忘记”。使用的值似乎是持久的,对类定义的编辑不会“粘住”。在后一种情况下,错误消息是:

  

警告:'myClass'的类文​​件已更改;但变化   无法应用,因为基于旧类文件的对象仍然存在   存在。如果使用这些对象,可能会得到意外结果。您   可以使用'clear'命令删除这些对象。看'帮助清除'   有关如何删除这些对象的信息。

即使在

之后我也收到了这条消息
>> clear all
>> clear functions
>> clear ans

尽管我试图清除它,但不知何故,类定义仍然存在。更糟糕的是,当我修改类的实例的值,然后清除它时,值不会被“遗忘”。为了说明,这里是myClass的源代码:

% a simple class definition that shows the problem that I cannot
% figure out how to redefine a class without restarting Matlab
classdef myClass < handle
    properties
        precursors = {'none'};
        numPre = {1};
        value = 1;
    end

    methods
        function obj = myClass(pre, num, val)
            % constructor
            if nargin > 0
                obj.precursors = pre;
                obj.numPre = num;
                obj.value = val;
            end
        end
        function v = sumVal(obj)
            % find the sum of the value of all precursors
            n = numel(obj.precursors);
            v = 0;
            for ii = 1:n
              pc = obj.precursors{ii};
              if isa(pc, 'myClass')
                  if ii==1
                      v = 0;
                  end
                  v = v + sumVal(pc) * obj.numPre{ii};
              else
                  v = obj.value;
              end
            end
        end
    end

    % only the following named instances may exist:
    enumeration
      grandpa   ({'none'},           {1},  1)
      father    ({myClass.grandpa},  {3}, -1)
      son       ({myClass.father},   {2}, -1) 
    end
end

在Matlab的新实例中,我执行以下操作:

>> son = myClass.son;
>> sumVal(son)

ans = 

     6

>> grandpa = myClass.grandpa;
>> grandpa.value = 5;
>> sumVal(son)

ans =

    30

到目前为止,这么好。 sumVal函数发现父亲和祖父,sumVal被正确计算(第一种情况下为6 * 1,第二种情况下为6 * 5)。

现在我删除“所有内容”(我认为):

>> clear all
>> clear functions
>> clear ans

我只创建了一个变量:

>> son = myClass.son;

现在是踢球者 - 意外的回答

>> sumVal(son)

ans =

    30

当我检查加载的变量时,我找到了

>> whos
Name    Size       Bytes  Class     Attributes

son      1x1         112  myClass

没有grandpa实例,并且未触及类定义文件。然而,grandpa(我创建,然后删除)的值在某种程度上是持久的。

当我对myClass.m文件做一个小改动,并尝试创建一个新变量(在clear all之后)时,我收到上面显示的消息。所有这些都引出了我的问题:

Matlab在哪里隐藏我的类的实例,以便变量在clear all后保持不变,如何清除工作区(不重新启动),以便类定义“重置”?

我不知道是否重要,但我使用的是Matlab 7.14.0.739(R2012a)

2 个答案:

答案 0 :(得分:6)

您有一个未被MATLAB销毁的中间实例myClass.father。你必须自己delete

>> clear grandpa
>> delete(son.precursors{1})
>> clear son
>> clear classes
>> son = myClass.son
son = 
    son    
>> sumVal(son)
ans =
     6

编辑: 或者,您可以向类中添加析构函数

    function delete(obj)
        if isa(obj.precursors{1}, 'myClass')
            delete(obj.precursors{1});
        end
    end

并使用delete(son)而不是将其留给clear函数来销毁。您可以将其扩展到您的案例,并递归删除树中的所有实例。

答案 1 :(得分:2)

这些实例“隐藏”在myClass枚举类本身中。 Matlab正在存储对每个命名实例的引用,因此当您像myClass.father一样引用它们时,您将获得相同的对象,而不是构造一个新对象。可能类似于值在类的Constant属性中的存储方式。

如果您有任何其他类引用myClass.xxx属性,枚举或Constant变量中的persistent枚举实例,它们也可以继续引用它们。< / p>

连续几次尝试clear classes而不是一次。

为了帮助调试这个,你可以在这个类的构造函数和析构函数中放置几个​​调试printf()语句,这样你就可以看到实际创建和清理实例的时间。

  function obj = myClass(pre, num, val)
      % constructor
      if nargin > 0
          obj.precursors = pre;
          obj.numPre = num;
          obj.value = val;
      end
      printf('myClass: created (%d, %d, nargin=%d)\n', obj.numPre, obj.value, nargin);
  end
  function delete(obj)
      printf('myClass: deleting (%d, %d)\n', obj.numPre, obj.value);
  end