复制对象
两种复制行为
存在两种基本的 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更改 hobj1 的 Data 属性的值,则所复制对象的 Data 属性值也会随之更改:
hobj1.Data = 5; hobj2.Data
ans =
5
由于 hobj2 和 hobj1 是同一对象的句柄,更改副本 hobj2 还会更改您通过句柄 hobj1 访问的数据:
hobj2.Data = 17; hobj1.Data
ans =
17为句柄变量重新赋值
为句柄变量重新赋值会生成与为任何 MATLAB 变量重新赋值相同的结果。创建一个对象并将其赋给 hobj1 时:
hobj1 = HdClass(3.14);
hobj1 引用新对象,而不是以前引用的同一对象(并且仍是由 hobj2 引用)。
清除句柄变量
从工作区中清除句柄时,MATLAB 会删除变量,但不会删除另一个句柄引用的对象。但是,如果没有指向对象的引用,则 MATLAB 会销毁该对象。
假定 hobj1 和 hobj2 都引用同一对象,您可以清除其中任一句柄而不会影响该对象:
hobj1.Data = 2^8; clear hobj1 hobj2
hobj2 =
HdClass with properties:
Data: 256如果您同时清除 hobj1 和 hobj2,则将不存在指向该对象的引用。MATLAB 将销毁该对象并释放该对象使用的内存。
删除句柄对象
要删除由任意数量的句柄引用的对象,请使用 delete。假定 hobj1 和 hobj2 都引用同一对象,请删除其中任一句柄。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 =
1hobj 还是 containers.Map 对象:
isa(hobj,'containers.Map')
ans =
1查询 hobj 的类会显示它是 containers.Map 对象:
class(hobj)
ans = containers.Map
class 函数会返回特定类的对象。