Skip to content

MATLAB - Copy Objects

In MATLAB, how an object is copied depends on its class. There are two fundamental behaviors: value and handle. Understanding this distinction is critical for writing predictable and bug-free object-oriented code, especially in large applications where object state is shared and modified.

By default, classes in MATLAB have value semantics. When you copy a value object, you create a new, completely independent instance of that object. It’s like photocopying a document: changes to the copy don’t affect the original.

All built-in MATLAB data types like double, char, and struct are value types.

classdef ValueClass
properties
Data = 0;
end
end
%% Create an instance of the value class
obj1 = ValueClass;
obj1.Data = 10;
%% Copy the object - MATLAB creates a deep, independent copy
obj2 = obj1;
%% Modify the copy
obj2.Data = 20;
%% Check the data of both objects
fprintf('obj1.Data = %d\n', obj1.Data); % Output: obj1.Data = 10
fprintf('obj2.Data = %d\n', obj2.Data); % Output: obj2.Data = 20
% As you can see, modifying obj2 did not affect obj1.

To create a handle class, you must inherit from the built-in handle class. When you copy a handle object variable, you are not creating a new object. Instead, you are creating a new reference (or handle) that points to the same underlying object. It’s like sharing a link to a Google Doc: anyone with the link can edit the same document.

classdef HandleClass < handle
properties
Data = 0;
end
end
%% Create an instance of the handle class
obj1 = HandleClass;
obj1.Data = 10;
%% "Copy" the object - this just copies the handle (reference)
obj2 = obj1;
%% Modify the object through the second handle
obj2.Data = 20;
%% Check the data of both objects
fprintf('obj1.Data = %d\n', obj1.Data); % Output: obj1.Data = 20
fprintf('obj2.Data = %d\n', obj2.Data); % Output: obj2.Data = 20
% Modifying the data via obj2 affected the single underlying object,
% so the change is visible through obj1 as well.

Best Practice: Creating a True Copy of a Handle Object

Section titled “Best Practice: Creating a True Copy of a Handle Object”

What if you have a handle object but need an independent copy? The best practice is to implement a custom copy method inside your handle class. This method will create a new instance of the class and copy the property values over.

This pattern often involves a protected copyElement method, which is a convention suggested by MathWorks for creating deep copies.

classdef CopyableHandle < handle
properties
Name
Data
end
methods
function obj = CopyableHandle(name, data)
if nargin > 0
obj.Name = name;
obj.Data = data;
end
end
% Public copy method
function new_obj = copy(self)
% Create a new object of the same class
new_obj = feval(class(self));
% Call a protected method to copy properties
self.copyElement(new_obj);
end
end
methods (Access = protected)
% Protected method to handle the actual property copying
function copyElement(self, new_obj)
props = properties(self);
for i = 1:length(props)
new_obj.(props{i}) = self.(props{i});
end
end
end
end
%% Create original object
original = CopyableHandle('Sensor A', [1, 2, 3]);
%% Use the custom copy method to create a deep copy
deepCopy = original.copy();
%% Modify the copy
deepCopy.Name = 'Sensor B Clone';
deepCopy.Data(1) = 99;
%% Display results to prove they are independent
disp('Original Object:');
disp(original);
disp('Copied Object:');
disp(deepCopy);
% Notice that only the copied object's properties have changed.

The copyobj function is primarily used for copying graphics objects (which are handle objects) from one parent to another, such as copying an axes from one figure to another. It is part of MATLAB’s older graphics system but remains useful in specific scenarios.

Key characteristics of copyobj:

  • The new object gets a new handle.
  • The new object’s Parent property is updated.
  • It generally does not copy callbacks or application data to avoid unintended behavior.
% Create a figure with some graphical objects
fig1 = figure('Name', 'Original Figure');
ax1 = axes('Parent', fig1);
plot(ax1, 1:10, rand(1, 10), 'LineWidth', 2);
title(ax1, 'Original Plot');
% Create a second figure to be the new parent
fig2 = figure('Name', 'Copied Figure');
% Copy the axes object from fig1 to fig2
newAx = copyobj(ax1, fig2);
% Modify the copy to prove it's independent
title(newAx, 'Copied Plot');
newAx.Color = [0.9 0.9 0.95]; % Change background color
% The original figure remains untouched.