Main Content

复制对象

两种复制行为

存在两种基本的 MATLAB® 对象 - 句柄和值。

在复制操作方面,对象的行为与 MATLAB 基础类型类似。副本是独立值。您对一个对象执行的操作不会影响该对象的副本。

句柄对象通过其句柄变量进行引用。句柄变量的副本引用同一个对象。您对句柄对象执行的操作对引用该对象的所有句柄变量可见。

句柄对象复制

如果您要定义类并想支持句柄对象复制,请参阅Implement Copy for Handle Classes

值对象复制行为

MATLAB 数值变量属于值对象。例如,您将 a 复制为变量 b 时,这两个变量彼此独立。更改 a 的值并不会更改 b 的值:

a = 8;
b = a;

现在重新为 a 赋值,而 b 不变:

a = 6;
b
b =
     8

清除 a 不会影响 b

clear a
b
b =
     8

值对象属性

作为值对象中的属性存储的值的复制行为与数值变量相同。例如,假定 vobj1 是带有属性 a 的值对象:

vobj1.a = 8; 

如果您将 vobj1 复制到 vobj2,然后更改 vobj1 属性 a 的值,则复制对象的属性 vobj2.a 的值将保持不变:

vobj2 =vobj1;
vobj1.a = 5;
vobj2.a
ans =
     8

句柄对象复制行为

此处提供的句柄类称为 HdClass,它定义称为 Data 的属性。

classdef HdClass < handle
   properties
      Data
   end
   methods
      function obj = HdClass(val)
         if nargin > 0
            obj.Data = val;
         end
      end
   end
end

创建此类的对象:

hobj1 = HdClass(8)

由于该语句不是通过分号终止的,因此 MATLAB 显示有关该对象的信息:

hobj1 = 

  HdClass with properties:

    Data: 8

变量 hobj1 是引用所创建对象的句柄。将 hobj1 复制到 hobj2 会生成引用同一对象的另一个句柄:

hobj2 = hobj1
hobj2 = 

  HdClass with properties:

    Data: 8

由于句柄引用该对象,复制句柄会将句柄复制为一个新的变量名称,但该句柄仍然引用同一对象。例如,假定 hobj1 是带有属性 Data 的句柄对象:

hobj1.Data
ans =

     8

更改 hobj1Data 属性的值,则所复制对象的 Data 属性值也会随之更改:

hobj1.Data = 5;
hobj2.Data
ans =

     5

由于 hobj2hobj1 是同一对象的句柄,更改副本 hobj2 还会更改您通过句柄 hobj1 访问的数据:

hobj2.Data = 17;
hobj1.Data
ans =

    17

为句柄变量重新赋值

为句柄变量重新赋值会生成与为任何 MATLAB 变量重新赋值相同的结果。创建一个对象并将其赋给 hobj1 时:

hobj1 = HdClass(3.14);

hobj1 引用新对象,而不是以前引用的同一对象(并且仍是由 hobj2 引用)。

清除句柄变量

从工作区中清除句柄时,MATLAB 会删除变量,但不会删除另一个句柄引用的对象。但是,如果没有指向对象的引用,则 MATLAB 会销毁该对象。

假定 hobj1hobj2 都引用同一对象,您可以清除其中任一句柄而不会影响该对象:

hobj1.Data = 2^8;
clear hobj1
hobj2
hobj2 = 

  HdClass with properties:

    Data: 256

如果您同时清除 hobj1hobj2,则将不存在指向该对象的引用。MATLAB 将销毁该对象并释放该对象使用的内存。

删除句柄对象

要删除由任意数量的句柄引用的对象,请使用 delete。假定 hobj1hobj2 都引用同一对象,请删除其中任一句柄。MATLAB 会删除该对象:

hobj1 = HdClass(8);
hobj2 = hobj1;
delete(hobj1)
hobj2
hobj2 = 

  handle to deleted HdClass

使用 clear 从工作区中删除变量。

修改对象

将对象传递给函数时,MATLAB 会将该对象的副本传递到函数工作区。如果该函数修改了对象,MATLAB 将仅修改函数工作区中对象的副本。句柄与值类之间的复制行为的区别在以下情况中很重要:

  • 值对象 - 函数必须返回对象的已修改副本。要在调用方工作区中修改该对象,请将函数输出分配具有相同名称的变量

  • 句柄对象 - 函数工作区中的副本引用同一个对象。因此,该函数无需返回已修改的副本。

测试句柄或值类

要确定对象是否为句柄对象,请使用 isa 函数。如果 obj 为某个类的对象,则此语句将确定 obj 是否为句柄:

isa(obj,'handle')

例如,containers.Map 类创建句柄对象:

hobj = containers.Map({'Red Sox','Yankees'},{'Boston','New York'});
isa(hobj,'handle')
ans =

     1

hobj 还是 containers.Map 对象:

isa(hobj,'containers.Map')
ans =

     1

查询 hobj 的类会显示它是 containers.Map 对象:

class(hobj)
ans =

containers.Map

class 函数会返回特定类的对象。

相关主题