主要内容

句柄类析构函数

基本知识

类的析构函数-一个名为删除这个MATLAB®在销毁句柄类的对象之前隐式调用。另外,用户定义的代码也可以调用删除显式地销毁对象。

Nondestructor-一个名为删除这不能满足有效析构函数的语法要求。因此,MATLAB在销毁句柄对象时不会隐式调用此方法。一个名为删除在值类中不是析构函数。一个名为删除属性的值类中HandleCompatible属性来真正的不是析构函数。

对象生命周期

方法属性

句柄类析构函数方法的语法

MATLAB在销毁句柄类的对象时调用句柄类的析构函数。MATLAB识别一个名为删除定义为类析构函数时删除作为具有适当语法的普通方法。

要成为有效的类析构函数,删除方法:

  • 必须定义一个标量输入参数,它是类的对象。

  • 一定不能定义输出参数

  • 不能密封静态,或摘要

  • 不能使用参数块用于输入参数验证。

此外,删除方法应该

  • 抛出错误,即使对象无效。

  • 为被销毁的对象创建新的句柄

  • 调用方法或访问子类的属性

MATLAB不调用不兼容删除方法在销毁类的对象时。一个不合格删除方法可以通过遮蔽对象来防止对象的破坏处理类删除方法。

一个删除由句柄兼容的值类定义的方法不是析构函数,即使删除方法由句柄子类继承。有关句柄兼容类的信息,请参见处理兼容类

声明删除作为一个普通的方法:

方法函数删除(obj)% obj始终是标量...结束结束

delete Called Element-Wise on Array

MATLAB调用删除方法分别为数组中的每个元素设置。因此,一个删除方法在每次调用时只传递一个标量参数。

调用删除删除句柄时不应出错,也不能采取任何操作。这种设计使删除处理混合包含有效和无效对象的对象数组。

期间处理对象删除方法执行

调用删除方法总是会导致对象的销毁。调用时,对象将被销毁删除在MATLAB代码中显式生成,或者由MATLAB调用时,因为对象不再从任何工作区可访问。一旦被称为,删除方法不能中止或阻止对象销毁。

一个删除方法可以访问正在删除的对象的属性。MATLAB不会破坏这些属性,直到删除对象的类和所有超类的方法完成执行。

如果一个删除方法创建包含被删除对象句柄的新变量,则这些句柄无效。后删除方法完成执行时,任何工作区中任何变量中已删除对象的句柄都是无效的。

isvalid方法返回类中的句柄对象删除方法,因为对象销毁是从调用方法时开始的。

MATLAB调用删除方法与构造顺序相反。即MATLAB调用子类删除超类之前的方法删除方法。

如果父类期望某个属性由子类管理,则父类不应在其父类中访问该属性删除方法。例如,如果一个子类使用继承的抽象属性来存储一个对象句柄,那么子类应该在它的子类中销毁这个对象删除方法,但超类不应在其删除方法。

金宝app支持销毁部分构造的对象

构造对象时发生的错误可能导致调用删除在对象完全创建之前。因此,类删除方法必须能够处理部分构造的对象。

例如,PartialObject删除方法确定是否数据属性在访问此属性包含的数据之前为空。类的构造函数参数赋值时发生错误的名字属性,MATLAB传递部分构造的对象进行删除。

classdefPartialObject < handle属性限制Name属性%到单元格数组的名字细胞数据结束方法函数h = PartialObject(name)如果nargin > 0 h.Name = name;h.Data.a = rand(10,1);结束结束函数删除(h)防止访问属性%的部分构造对象如果~isempty(h.Data) t = h.Data.a;disp (t)其他的disp (“数据为空”结束结束结束结束

类调用构造函数时,将发生错误字符向量,而不是所需的单元格数组:

obj = PartialObject(“测试”

MATLAB将部分构造的对象传递给删除方法。的值,构造函数未设置数据属性时发生错误的名字财产。

数据为空设置'PartialObject'类的'Name'属性错误:

何时定义析构函数方法

使用一个删除方法在MATLAB销毁对象之前执行清理操作。MATLAB调用删除方法,即使执行被Ctrl-c中断或出现错误。

如果在构造句柄类期间发生错误,MATLAB将调用对象上的类析构函数以及属性中包含的任何对象和任何初始化基类的析构函数。

例如,假设一个方法打开一个文件进行写入,而您想要在您的文件中关闭该文件删除方法。的删除方法可以调用文件关闭对象中存储的文件标识符文件标识属性:

函数删除(obj)文件关闭(obj.FileID);结束

类层次结构中的析构函数

如果创建类的层次结构,则每个类都可以定义自己的类删除方法。当销毁一个对象时,MATLAB调用删除层次结构中每个类的方法。定义一个删除方法中的处理类不重写处理删除方法。子类删除方法扩充超类删除方法。

继承一个密封删除方法

类不能定义有效的析构函数密封.类的实例化时,MATLAB返回一个错误密封删除方法。

通常,将方法声明为密封防止子类重写该方法。然而,一个密封方法命名删除不是有效的析构函数并不阻止子类定义自己的析构函数。

例如,如果一个超类定义了一个名为删除这不是一个有效的析构函数,但是密封,然后是子类:

  • 可以定义有效的析构函数(总是命名为删除).

  • 不能定义命名为删除不是有效的析构函数。

异构层次结构中的析构函数

异构类层次结构要求将异构数组传递给的所有方法都必须密封。但是,该规则不适用于类析构函数方法。因为析构函数方法不能密封,所以可以在异构层次结构中定义一个有效的析构函数,该析构函数不密封,但具有析构函数的功能。

有关异构层次结构的信息,请参见设计异构类层次结构

对象生命周期

MATLAB调用删除当对象的生命周期结束时,方法返回。对象的生命周期在以下情况下结束:

  • 不再在任何地方引用

  • 通过调用删除在把手上

函数内部

被局部变量或输入参数引用的对象的生命周期从变量被赋值到它被重新赋值、清除或不再在该函数或任何句柄数组中被引用。

当显式清除变量或其函数结束时,变量将超出作用域。变量超出作用域且其值属于定义了类的句柄类删除方法,MATLAB调用该方法。MATLAB定义了函数中变量之间没有顺序。当同一个函数包含多个值时,不要假设MATLAB会先销毁一个值再销毁另一个值。

处理对象销毁时的序列

MATLAB调用删除方法在销毁对象时按以下顺序执行:

  1. 删除方法获取对象的类

  2. 删除方法,从直接的超类开始,沿着层次结构向上延伸到最一般的超类

MATLAB调用删除按类定义中指定的顺序在层次结构中同一级别的超类的方法。例如,下面的类定义指定supclass1之前supclass2.MATLAB调用删除的方法supclass1之前删除的方法supclass2

classdefmyClass < supclass1 & supclass2

在给每个人打电话之后删除方法,MATLAB销毁专属于其方法被调用的类的属性值。属性值的破坏包含其他句柄对象可能导致调用删除方法,当没有对这些对象的其他引用时。

超类删除方法不能调用方法或访问属于子类的属性。

使用循环引用的对象的销毁

考虑一组对象引用该组中的其他对象,这样引用就形成了一个循环图。本例中,MATLAB:

  • 如果只在循环中引用对象,则销毁对象

  • 不破坏对象,只要有一个外部引用的任何对象从MATLAB变量之外的周期

MATLAB破坏对象的顺序与构造顺序相反。有关更多信息,请参见在delete方法执行期间处理对象

限制对对象删除方法的访问

通过显式调用来销毁句柄对象删除在对象上:

删除(obj)

类可以通过设置对象的属性来防止显式销毁对象删除方法访问属性来私人.类的方法可以调用私人删除方法。

如果这个类删除方法访问属性是受保护的,只有类和子类的方法可以显式删除该类的对象。

然而,当一个对象的生命周期结束时,MATLAB调用该对象的删除方法时销毁对象,而不考虑方法的值访问属性。

继承的私有删除方法

类析构函数的行为不同于被重写方法的正常行为。MATLAB执行删除方法,即使是这样删除方法不是公共

当显式调用对象的删除方法,MATLAB检验删除方法访问属性中定义对象的类,但不在对象的超类中。类的超类私人删除方法不能防止子类对象的破坏。

声明私有删除方法对密封类最有意义。在类没有被密封的情况下,子类可以用公共访问定义自己的删除方法。MATLAB调用私有超类删除方法作为对公共子类的显式调用的结果删除方法。

非析构函数删除方法

类可以实现命名的方法删除这不是有效的类析构函数。MATLAB在销毁对象时不隐式调用此方法。在这种情况下,删除行为像一个普通的方法。

例如,如果超类实现了密封方法命名删除如果不是有效的析构函数,则MATLAB不允许子类重写此方法。

一个删除由值类定义的方法不能是类析构函数。

外部引用MATLAB对象

MATLAB不管理涉及执行自己的对象生命周期管理(即垃圾收集)的外部语言的对象生命周期。MATLAB无法检测何时可以安全销毁循环引用中使用的对象,因为当外部引用已被销毁时,外部环境不会通知MATLAB。

如果不能避免对MATLAB对象的外部引用,可以通过销毁MATLAB中的对象显式地打破循环引用。

下面的部分描述了在使用Java时如何管理这种情况®引用MATLAB对象的对象。

Java引用可以阻止析构函数的执行

Java不支持MATLAB对金宝app象使用的对象析构函数。因此,管理同时包含Java和MATLAB对象的应用程序中使用的所有对象的生命周期非常重要。

持有MATLAB对象引用的Java对象可以防止MATLAB对象的删除。在这些情况下,MATLAB不调用句柄对象删除方法,即使没有句柄变量引用该对象。确保您的删除方法执行,调用删除在句柄变量超出作用域之前,在对象上显式地执行。

为引用MATLAB对象的Java对象定义回调时,可能会出现问题。

例如,CallbackWithJava类创建一个Javacom.mathworks.jmi.Callback对象,并将类方法赋值为回调函数。结果是一个Java对象,该对象通过函数句柄回调具有对句柄对象的引用。

classdefCallbackWithJava < handle方法函数obj = CallbackWithJava jo = com.mathworks.jmi.Callback;集(乔,“DelayedCallback”, @obj.cbFunc);将方法分配为回调jo.postCallback结束函数cbFunc(obj,varargin) c = class(obj);disp ([类上的Java对象回调c])结束函数删除(obj) c = class(obj);disp ([调用类的ML对象析构函数c])结束结束结束

假设你创建了一个CallbackWithJava对象:

函数testDestructor cwj = CallbackWithJava...结束

类的实例CallbackWithJava类创建com.mathworks.jmi.Callback对象并执行回调函数:

testDestructor
cwj = CallbackWithJava没有属性。Java对象回调类CallbackWithJava

句柄变量,cwj,只存在于函数工作区中。但是,MATLAB不调用该类删除函数结束时,方法。的com.mathworks.jmi.Callback对象仍然存在,并保存对对象的引用CallbackWithJava类,它可以防止MATLAB对象的破坏。

清晰的
警告:'CallbackWithJava'类对象存在。无法清除此类或其任何超类。

为了避免造成不可访问的对象,调用删除在失去MATLAB对象的句柄之前。

函数testDestructor cwj = CallbackWithJava...删除(cwj)结束

管理应用程序中的对象生命周期

使用Java或其他外部语言对象的MATLAB应用程序应该管理所涉及对象的生命周期。典型的用户界面应用程序从MATLAB对象引用Java对象,并在引用MATLAB对象的Java对象上创建回调。

你可以用不同的方式打破这些循环引用:

  • 显式调用删除当它们不再需要时,对MATLAB对象进行修改

  • 注销引用MATLAB对象的Java对象回调

  • 使用同时引用Java回调和MATLAB对象的中间句柄对象。

相关的话题