文档

处理类的析构函数

基本知识

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

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

对象生命周期

方法属性

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

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

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

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

  • 一定不能定义输出参数

  • 不能密封静态,或摘要

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

此外,删除方法应该

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

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

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

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

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

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

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

删除数组上的Called Element-Wise

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

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

处理对象时删除方法执行

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

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

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

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

MATLAB调用删除方法的构造顺序相反。也就是说,MATLAB调用子类删除方法在超类删除方法。

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

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

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

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

classdefPartialObject <处理属性限制Name属性%到单元格数组名称单元格数据结束方法函数h = PartialObject(名称)如果h.Name = name;h.Data.a =兰德(10,1);结束结束函数删除(h)防止访问属性%的部分构造对象如果~isempty(h.Data) t = h.Data.a;disp (t)其他的disp (数据是空的结束结束结束结束

类调用构造函数时,将发生错误字符Vector代替所需的单元格数组:

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

classdef我的班级

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

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

循环引用对象的销毁

考虑一组对象,它们引用集合中的其他对象,使这些引用形成一个循环图。在这种情况下,MATLAB:

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

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

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

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

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

删除(obj)

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

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

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

继承的私有删除方法

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

当显式调用对象的删除方法,MATLAB验证删除方法访问属性在定义对象的类中,但不在对象的超类中。类的超类私人删除方法无法阻止子类对象的销毁。

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

Nondestructor删除方法

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

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

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

Java对象引用MATLAB对象

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

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

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

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

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

classdefCallbackWithJava <处理方法函数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。类CallbackWithJava上的Java对象回调

处理变量,cwj,只存在于函数工作区中。然而,MATLAB并不调用该类删除方法。的com.mathworks.jmi.Callback对象仍然存在,并保存对对象的引用CallbackWithJava类,防止破坏MATLAB对象。

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

为了避免导致无法访问的对象,调用删除在失去MATLAB对象的句柄之前。

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

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

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

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

  • 当不再需要MATLAB对象时,显式地调用delete

  • 取消注册引用MATLAB对象的Java对象回调

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

相关的话题