Matlab中句柄类和值类的比较

本文深入探讨了MATLAB中的值类和句柄类的区别。值类在赋值或传递时创建对象副本,而句柄类则引用同一对象。句柄类适用于需要共享和修改的对象,如图形对象。值类适用于独立的数据结构,修改不涉及其他对象。MATLAB的内置类如数值和逻辑是值类,而图形对象是句柄类。理解这两种类的行为对于有效使用MATLAB至关重要。
摘要由CSDN通过智能技术生成

句柄类和值类的比较

基本差异

​        值类构造函数返回一个与其赋值变量相关联的对象。如果对此变量重新赋值,MATLAB® 会创建原始对象的独立副本。如果将此变量传递给函数以修改它,函数必须将修改后的对象以输出参数形式返回。

        句柄类构造函数返回句柄对象,该对象是对所创建对象的引用。可以将句柄对象赋给多个变量或将它传递给函数,而不会导致 MATLAB 创建原始对象的副本。函数对作为输入参数传递的句柄对象进行修改后,不必返回该对象。

        所有句柄类都派生自抽象的 handle 类。​

创建值类

        默认情况下,MATLAB 类是值类。以下定义创建名为 MyValueClass 的值类:

classdef MyValueClass 
   
...

end 

创建句柄类

        要创建handle类,请从handle类派生该类。

classdef MyHandleClass < handle
   
...

end 

MATLAB 内置类的行为

        MATLAB 基础类是值类(数值、logical、char、cell、struct 以及函数句柄)。例如,如果创建 int32 类的对象并复制该对象,结果会是两个独立的对象。更改a的值不会导致b的值发生更改。此行为是表示值的类的典型行为。

a = int32(7);
b = a;
a = a^4;


b
   7

        MATLAB 图形对象作为句柄对象实现,因为它们表示视觉元素。例如,创建一个图形线条对象,并将它的句柄复制到另一个变量。这两个变量引用同一个线条对象。

x = 1:10; y = sin(x);
l1 = line(x,y);
l2 = l1;

        使用句柄的任一副本设置线条对象的属性。

set(l2,'Color','red') 
set(l1,'Color','green') 
get(l2,'Color')


ans =

     0     1     0

        对 l2 句柄调用 delete 函数会销毁该线条对象。如果尝试在 l1 行设置 Color 属性,set 函数将返回错误。

delete(l2)
set(l1,'Color','blue')


Error using matlab.graphics.primitive.Line/set
Invalid or deleted object.

        如果通过删除任一现有句柄来删除对象,则所有副本都将变为无效,因为删除了被所有句柄引用的单个对象。

        删除句柄对象不同于清除句柄变量。在图形对象层次结构中,对象的父级保存对该对象的引用。例如,父坐标区包含对 l1 和 l2 引用的线条对象的引用。如果从工作区中清除这两个变量,该对象仍然存在。

​        有关句柄对象行为的详细信息,可以参考句柄对象行为

用户定义的值类

        MATLAB 将值类的对象与该对象的赋值变量相关联。当将值对象复制到另一个变量或将值对象传递给函数时,MATLAB 会创建该对象和该对象包含的所有数据的独立副本。对原始对象的更改不会影响到新对象。值对象的行为类似于 MATLAB 数值类和 struct 类。每个属性的行为本质上都类似于 MATLAB 数组。

        值对象始终与一个工作区或临时变量相关联。当值对象的变量超出作用域或被清除时,值对象会超出作用域。此处没有对值对象的引用,只有作为独立对象的副本。

值对象行为

        以下是一个值类,它在其 Number 属性中存储一个值。默认属性值是数字 1。

classdef NumValue
   properties
      Number = 1
   end
end

        创建一个为变量 a 赋值的 NumValue 对象。

a = NumValue
a = 


  NumValue with properties:

    Number: 1

        将 a 的值赋给另一个变量 b。

b = a
b = 


  NumValue with properties:

    Number: 1

        变量 a 和 b 是独立的。更改 a 的 Number 属性的值不会影响 b 的 Number 属性。

a.Number = 7
a = 

  NumValue with properties:

    Number: 7
b
b = 

  NumValue with properties:

    Number: 1

修改函数中的值对象

​        将值对象传递给函数时,MATLAB 会在函数工作区中创建该对象的副本。由于值对象的副本是独立的,因此函数不会修改调用方工作区中的对象。因此,修改值对象的函数必须返回修改后的对象,用以在调用方工作区中重新赋值。具体可以参考对象修改。​

用户定义的句柄类

        从 handle 类派生的类的实例是对底层对象数据的引用。复制句柄对象时,MATLAB 会复制句柄,但不会复制存储在对象属性中的数据。副本引用与原始句柄相同的对象。如果更改原始对象的属性值,复制的句柄将引用相同的更改。

句柄对象行为

        以下是一个句柄类,它在 Number 属性中存储一个值。默认属性值是数字 1。

classdef NumHandle < handle
   properties
      Number = 1
   end
end

        创建一个为变量 a 赋值的 NumHandle 对象。

a = NumHandle
a = 

  NumHandle with properties:

    Number: 1

        将 a 的值赋给另一个变量 b。

b = a
b = 

  NumHandle with properties:

    Number: 1

        变量 a 和 b 引用同一底层对象。更改 a 的 Number 属性的值也将更改 b 的 Number 属性的值。即,a 和 b 引用同一个对象。

a.Number = 7
a = 

  NumHandle with properties:

    Number: 7
b
b = 

  NumHandle with properties:

    Number: 7

修改函数中的句柄对象

        当将句柄对象传递给函数时,MATLAB 会在函数工作区中创建句柄的副本。由于句柄的副本引用相同的底层对象,因此修改句柄对象的函数实际上也会修改调用方工作区中的对象。因此,函数对作为输入参数传递的句柄对象进行修改后,不必将修改后的对象返回给调用方。

删除句柄

​        可以通过显式调用句柄的 delete 方法来销毁句柄对象。删除句柄类对象的句柄会使所有句柄无效。例如:

a = NumHandle;
b = a;
delete(a)
b.Number


Invalid or deleted object.

​​​        对句柄对象调用 delete 会调用该对象的析构函数。具体可以参考句柄类析构函数

确定对象的相等性

        值对象的相等意味着这些对象属于同一个类并且具有相同的状态。

        句柄对象的相等意味着句柄变量引用同一个对象。还可以识别引用同一类且具有相同状态的不同对象的句柄变量。

值对象的相等性

​        要确定值对象是否大小相同且内容等值,请使用 isequal。例如,使用先前定义的 NumValue 类创建两个实例并测试相等性:

a = NumValue;
b = NumValue;
isequal(a,b)


ans =

     1

        a 和 b 是独立的,因此不是同一个对象。然而,二者都表示相同的值。如果更改由一个值对象表示的值,这些对象将不再相等。

a = NumValue;
b = NumValue;
b.Number = 7;
isequal(a,b)


ans =

     0

        ​值类没有默认的 eq 方法来实现 == 运算。

句柄对象的相等性

​        句柄对象从 handle 基类继承 eq 方法。可以使用 == 和 isequal 测试句柄对象之间的两种不同关系:​

  • 句柄引用同一个对象:== 和 isequal 返回 true。

  • 句柄引用同一类且具有相同值的对象,但它们不是同一对象 - 只有 isequal 返回 true。

        使用先前定义的 NumHandle 类创建对象并复制句柄。

a = NumHandle;
b = a;

        使用 == 和 isequal 测试相等性。

a == b

ans =

     1



isequal(a,b)

ans =

     1

        使用默认值创建 NumHandle 类的两个实例。

a = NumHandle;
b = NumHandle;

        确定 a 和 b 是否引用同一个对象。

a == b


ans =

     0

        确定 a 和 b 是否具有相同的值。

isequal(a,b)


ans =

     1

句柄类支持的功能​

从 handle 类派生的类能够:

  • ​继承多个有用的方法(Handle Class Methods)

  • ​定义事件和侦听程序(事件和侦听程序语法)

  • ​定义动态属性(动态属性 - 向实例添加属性)​

  • ​实现 set 和 get 方法(为属性实现 set/get 接口)

  • ​自定义复制行为(Implement Copy for Handle Classes)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值