罗兰在MATLAB的艺术

把想法变成MATLAB

请注意

罗兰在MATLAB的艺术已经存档,不会被更新。

解构析构函数

珍妮弗·黑,我很高兴地介绍嘉宾MATLAB对象系统的经理团队。今天珍妮弗将分享一些想法当对象被销毁在MATLAB和如何控制这一过程的各个方面。

内容

为什么定义一个析构函数

清除一个类的实例时,MATLAB自动清理该对象拥有的属性的值。例如,如果我有一个信号类与属性存储双值矩阵,这个矩阵被摧毁时信号被摧毁。然而,有时可能需要额外的行动来处理外部资源。

让我们考虑下面的类:

类型FileReader1
classdef FileReader1 <处理属性文件标识结束结束

在MATLAB中,文件标识符返回的是一个整数打开外部文件函数。它使用文件I / O等功能从文件中读写入文件访问该文件。如果打开外部文件不能打开文件,它将返回1。

如果我有一个开放的FileReader命名读者在我的工作区,清算读者将导致MATLAB明确的值存储在我的吗文件标识财产。现在走了,但是文件还开着。清算文件标识没有首先关闭文件意味着文件是敞开即使它不再被使用。如果这种情况发生的次数足够多,我可能会耗尽系统文件句柄。

让我们来看看定义析构函数关闭文件句柄。析构函数是类的一个方法负责清理资源拥有的对象。在MATLAB中,处理超类是用于所有类型的对象有一个独特的身份独立于他们的当前状态。与数字、矩阵等,处理对象代表独特的事情有开始和结束,可能会改变内部状态。的任何子类处理可以定义一个特殊的方法命名吗删除,通常被称为一个析构函数。在我的情况下FileReader类,我可以正确的泄漏文件句柄的问题通过实现自己的析构函数:

类型FileReader2
classdef FileReader2 <处理属性最终文件标识方法函数删除(readerObj)文件关闭(readerObj.FileID);结束结束结束

定义一个析构函数

一个MATLAB析构函数接受一个输入参数,被摧毁的对象,不返回任何输出。输入对象总是标量即使MATLAB对象数组超出范围。

在MATLAB类可以定义一个命名方法删除这不是一个析构函数。一个删除方法用不同的签名不是一个析构函数,也不是一个静态的删除方法。例如,定义方法采取多个输入参数或返回任何输出参数意味着方法不是视为一个对象析构函数。

调用析构函数

一个对象析构函数可以被显式地通过调用删除方法,或含蓄地通过MATLAB,例如当一个变量是清除或超出范围。让我们考虑一下这两种行为之间的区别。这样做我将添加一个构造函数和readData方法对我的类:

类型FileReader3
classdef FileReader3 <处理属性(SetAccess =保护)文件标识= 1;文件名结束函数方法读者= FileReader3(帧)如果ischar(帧)读者。文件名=帧;读者。文件标识= fopen(fname,'r'); end end function colorData = readData(reader) if reader.FileID == -1 error('No file name has been specified for this FileReader. No data will be read.'); else colorData = fscanf(reader.FileID,'%f',[3,inf]); colorData = colorData'; frewind(reader.FileID); end end function delete(reader) if reader.FileID ~= -1 s = sprintf('Closing %s', reader.FileName); disp(s); fclose(reader.FileID); end end end end

首先,让我们考虑一下这种情况:我有一个变量持有FileReader:

myReader = FileReader3 (“colorData.txt”);

显式地调用删除myReader调用析构函数,然后摧毁了FileReader。的myReader变量仍然在我的工作区,但其处理不再是有效的:

删除(myReader);
关闭colorData.txt
isvalid (myReader)
ans = 0

一个隐式调用析构函数会发生如果我清楚myReader从我的工作:

myReader = FileReader3 (“colorData.txt”);清晰的myReader
关闭colorData.txt

析构函数也将隐式地叫如果我变量超出范围,例如因为结束的函数。为了说明这一点,让我们添加一个helper函数,我创建了一个FileReader:

类型readDataFromFile
函数colorData = readDataFromFile(文件名)myReader = FileReader3(文件名);colorData = readData (myReader);结束

当我打电话给我的新助手功能,myReader在函数中创建并将函数结束的时候出去的范围。这导致MATLAB明确的变量,结果在一个隐含的调用删除方法:

colordata = readDataFromFile (“colorData.txt”);
关闭colorData.txt

现在,让我们对比我们刚刚讨论过的有一个单一的处理的情况我有多个处理相同FileReader。这一切发生的时候,例如,当我创建一个处理对象,然后将处理分配给另一个工作空间变量:

reader1 = FileReader3 (“colorData.txt”);reader2 = reader1;

与这两个处理相同FileReader现在在我的空间,我将显式调用删除,然后使用isvalid方法来看看发生了什么FileReader对象:

删除(reader1);
关闭colorData.txt
isvalid (reader1)
ans = 0
isvalid (reader2)
ans = 0

正如预期,reader1处理不再有效,但请注意reader2也不再有效。为什么会这样?因为当我显式调用删除析构函数被调用和对象被销毁无论有多少句柄引用该对象。

现在,让我们看看会发生什么时,隐式地调用析构函数。再一次让我们创建两个处理相同FileReader:

reader1 = FileReader3 (“colorData.txt”);reader2 = reader1;

但这一次,而不是显式地调用析构函数,我只清楚的一个句柄。正如我们前面看到的,这可能会导致一个隐含的调用删除方法:

清晰的reader1;isvalid (reader2)
ans = 1

为什么reader2仍然有效,为什么是我的析构函数不叫什么?由于MATLAB时只会隐式地调用析构函数去年引用一个对象清除。作为reader2仍然存在于我的工作区,底层FileReader不是毁灭。

通常一个析构函数被定义为一个公共方法,但它也可以声明为私有或受保护的方法。这使得私人将防止代码以外的类显式地调用析构函数。同样,一个受保护的析构函数只能显式从相同的类或方法调用子类的方法。MATLAB总是可以隐式地调用析构函数,甚至宣布私人或保护。你可以选择限制访问你的析构函数在一个情况下你想防止意外删除一个对象,例如当你有一个单例对象。

处理包含在其他结构

当处理存储领域的一个结构或一个细胞一个细胞数组,或作为另一个对象的属性?顶级容器变量被摧毁时,也将被摧毁,其处理对象删除方法隐式地调用当且仅当不存在任何其他引用的对象。让我们来看一个示例与结构:

年代。myReader = FileReader3 (“colorData.txt”);清晰的年代
关闭colorData.txt

请注意,FileReader存储在myReader领域的年代已被摧毁。然而,正如我们之前看到的,另一个句柄是一样的FileReader将防止破坏的对象:

reader4 = FileReader3 (“colorData.txt”);年代。myReader = reader4;清晰的年代isvalid (reader4)
ans = 1

即使在清算年代,我们看到,reader4仍然是有效的。第二个处理预防对象的隐式破坏。

类层次结构

到目前为止,我们一直在关注独立的类的例子,但是类层次结构的一部分吗?在MATLAB中,每个类有能力控制自己的破坏行为。层次的类,每个类可以定义自己的析构函数。因此,析构函数不能被定义为一个密封方法。

当一个对象被销毁,MATLAB将调用对象的析构函数类的第一,如果它被定义。接下来,每个父类的析构函数被调用时,从最直接的超类。

析构函数可以引用类本身的属性,包括属性从超类继承,但一般不应引用属性的一个子类。为什么?因为执行父类的析构函数时,其子类析构函数已经执行,和可能无效值的属性。

你如何使用析构函数?

既然我们已经讨论了使用MATLAB中的析构函数方法的基本知识,我想听听你的经历。你已经在使用析构函数吗?如果你有任何有趣的应用程序或问题,我很高兴听到他们在这里




发表与MATLAB®R2013a


  • 打印
  • 发送电子邮件

评论

留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。