我遇到了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)
答案 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