MATLAB - 复制对象
MATLAB - 理解对象复制
Section titled “MATLAB - 理解对象复制”在 MATLAB 中,对象的复制方式取决于其类。有两种基本行为:值(value)和句柄(handle)。理解这种区别对于编写可预测且无错误的对象导向代码至关重要,尤其是在对象状态被共享和修改的大型应用程序中。
值对象:独立副本
Section titled “值对象:独立副本”默认情况下,MATLAB 中的类具有值语义(value semantics)。当您复制一个值对象时,您会创建一个全新的、完全独立的该对象实例。这就像复印一份文件:对副本的更改不会影响原件。
所有内置的 MATLAB 数据类型,如 double、char 和 struct 都是值类型。
classdef ValueClass properties Data = 0; endend%% 创建值类的实例obj1 = ValueClass;obj1.Data = 10;
%% 复制对象 - MATLAB 会创建一个独立的深拷贝obj2 = obj1;
%% 修改副本obj2.Data = 20;
%% 检查两个对象的数据fprintf('obj1.Data = %d\n', obj1.Data); % 输出: obj1.Data = 10fprintf('obj2.Data = %d\n', obj2.Data); % 输出: obj2.Data = 20
% 如你所见,修改 obj2 并未影响 obj1。句柄对象:共享引用
Section titled “句柄对象:共享引用”要创建句柄类,您必须继承内置的 handle 类。当您复制句柄对象变量时,您不是在创建一个新对象。相反,您是创建了一个指向同一个底层对象的新引用(或句柄)。这就像共享一个 Google 文档的链接:任何拥有该链接的人都可以编辑同一份文档。
classdef HandleClass < handle properties Data = 0; endend%% 创建句柄类的实例obj1 = HandleClass;obj1.Data = 10;
%% “复制”对象 - 这只是复制了句柄(引用)obj2 = obj1;
%% 通过第二个句柄修改对象obj2.Data = 20;
%% 检查两个对象的数据fprintf('obj1.Data = %d\n', obj1.Data); % 输出: obj1.Data = 20fprintf('obj2.Data = %d\n', obj2.Data); % 输出: obj2.Data = 20
% 通过 obj2 修改数据影响了底层唯一的对象,% 因此 obj1 也能看到此更改。最佳实践:创建句柄对象的真副本
Section titled “最佳实践:创建句柄对象的真副本”如果您有一个句柄对象,但需要一个独立的副本怎么办?最佳实践是在您的句柄类中实现一个自定义的 copy 方法。该方法将创建一个该类的新实例并复制属性值。
此模式通常涉及一个受保护的 copyElement 方法,这是 MathWorks 建议的用于创建深拷贝的约定。
示例:带有 copy 方法的句柄类
Section titled “示例:带有 copy 方法的句柄类”classdef CopyableHandle < handle properties Name Data end
methods function obj = CopyableHandle(name, data) if nargin > 0 obj.Name = name; obj.Data = data; end end
% 公共复制方法 function new_obj = copy(self) % 创建一个同类的新对象 new_obj = feval(class(self));
% 调用受保护的方法来复制属性 self.copyElement(new_obj); end end
methods (Access = protected) % 处理实际属性复制的受保护方法 function copyElement(self, new_obj) props = properties(self); for i = 1:length(props) new_obj.(props{i}) = self.(props{i}); end end endend%% 创建原始对象original = CopyableHandle('Sensor A', [1, 2, 3]);
%% 使用自定义复制方法创建深拷贝deepCopy = original.copy();
%% 修改副本deepCopy.Name = 'Sensor B Clone';deepCopy.Data(1) = 99;
%% 显示结果以证明它们是独立的disp('原始对象:');disp(original);
disp('复制对象:');disp(deepCopy);% 请注意,只有复制对象的属性发生了变化。旧版函数:用于图形的 copyobj
Section titled “旧版函数:用于图形的 copyobj”copyobj 函数主要用于复制图形对象(它们是句柄对象)从一个父级到另一个父级,例如将 axes 从一个 figure 复制到另一个 figure。它是 MATLAB 较旧的图形系统的一部分,但在特定情况下仍然有用。
copyobj 的主要特点:
- 新对象获得一个新的句柄。
- 新对象的
Parent属性会更新。 - 它通常不复制回调或应用程序数据,以避免意外行为。
使用 copyobj 的示例
Section titled “使用 copyobj 的示例”% 创建一个带有一些图形对象的图窗fig1 = figure('Name', 'Original Figure');ax1 = axes('Parent', fig1);plot(ax1, 1:10, rand(1, 10), 'LineWidth', 2);title(ax1, 'Original Plot');
% 创建第二个图窗作为新的父级fig2 = figure('Name', 'Copied Figure');
% 将轴对象从 fig1 复制到 fig2newAx = copyobj(ax1, fig2);
% 修改副本以证明它是独立的title(newAx, 'Copied Plot');newAx.Color = [0.9 0.9 0.95]; % 更改背景颜色
% 原始图窗保持不变。