Implement Copy for Handle Classes
Copy Method for Handle Classes
Copying a handle variable results in another handle variable that refers to the same object. You can add copy functionality to your handle class by subclassing matlab.mixin.Copyable
. The inherited copy
method enables you to make shallow copies of objects of the class. The CopyObj
class shows the behavior of copy operations.
classdef CopyObj < matlab.mixin.Copyable properties Prop end end
Create an object of the CopyObj
class and assign the handle of a line
object to the property Prop
.
a = CopyObj; a.Prop = line;
Copy the object.
b = copy(a);
Confirm that the handle variables a
and b
refer to different objects.
a == b
ans = logical 0
However, the line
object referred to by
a.Prop
has not been copied. The handle in
a.Prop
refers to the same object as the handle in
b.Prop
.
a.Prop == b.Prop
ans = logical 1
For more detailed information on the behavior of the copy operation, see copy
.
Customize Copy Operation
Customize handle object copy behavior by deriving your class from matlab.mixin.Copyable
. The matlab.mixin.Copyable
class is an abstract base class that derives from the handle class. matlab.mixin.Copyable
provides a template for customizing object copy operations by defining:
copy
— Sealed method that defines the interface for copying objectscopyElement
— Protected method that subclasses can override to customize object copy operations for the subclass
The matlab.mixin.Copyable
copy
method, calls the copyElement
method. Your subclass customizes the copy operation by defining its own version of copyElement
.
The default implementation of copyElement
makes shallow copies of all the nondependent properties. copyElement
copies each property value and assigns it to the new (copied) property. If a property value is a handle object, copyElement
copies the handle, but not the underlying data.
To implement different copy behavior for different properties, override copyElement
. For example, the copyElement
method of the SpecializedCopy
class:
Creates a new class object
Copies the value of
Prop1
to the new objectReinitializes the default value of
Prop2
by adding a timestamp when the copy is made
classdef SpecializedCopy < matlab.mixin.Copyable properties Prop1 Prop2 = datestr(now) end methods(Access = protected) function cp = copyElement(obj) cp = SpecializedCopy; cp.Prop1 = obj.Prop1; cp.Prop2 = datestr(now); end end end
Create an object of the class and assign a value to Prop1
:
a = SpecializedCopy; a.Prop1 = 7
a = SpecializedCopy with properties: Prop1: 7 Prop2: '17-Feb-2015 17:51:23'
Use the inherited copy
method to create a copy of a
:
b = copy(a)
b = SpecializedCopy with properties: Prop1: 7 Prop2: '17-Feb-2015 17:51:58'
The copy (object b
) has the same value for Prop1
, but the subclass copyElement
method assigned a new value to Prop2
. Notice the different timestamp.
Copy Properties That Contain Handles
Copying an object also copies the values of object properties. Object properties can contain other objects, including handle objects. If you simply copy the value of a property that contains a handle object, you are actually copying the handle, not the object itself. Therefore, your copy references the same object as the original object. Classes that derive from the matlab.mixin.Copyable
class can customize the way the copy method copies objects of the class.
Class to Support Handle Copying
Suppose that you define a class that stores a handle in an object property. You want to be able to copy objects of the class and want each copy of an object to refer to a new handle object. Customize the class copy behavior using these steps:
Create a subclass of
matlab.mixin.Copyable
.Override
copyElement
to control how the property containing the handle is copied.Because the property value is a handle, create a new default object of the same class.
Copy property values from the original handle object to the new handle object.
The HandleCopy class customizes copy operations for the property that contains a handle object. The ColorProp class defines the handle object to assign to Prop2
:
Create an object and assign property values:
a = HandleCopy; a.Prop1 = 7; a.Prop2 = ColorProp;
Make a copy of the object using the copy
method inherited from matlab.mixin.Copyable
:
b = copy(a);
Demonstrate that the handle objects contained by objects a
and b
are independent. Changing the value on object a
does not affect object b
:
a.Prop2.Color = 'red'; b.Prop2.Color
ans = blue
HandleCopy
The HandleCopy
class customizes the copy operation for objects of this class.
classdef HandleCopy < matlab.mixin.Copyable properties Prop1 % Shallow copy Prop2 % Handle copy end methods (Access = protected) function cp = copyElement(obj) % Shallow copy object cp = copyElement@matlab.mixin.Copyable(obj); % Get handle from Prop2 hobj = obj.Prop2; % Create default object new_hobj = eval(class(hobj)); % Add public property values from orig object HandleCopy.propValues(new_hobj,hobj); % Assign the new object to property cp.Prop2 = new_hobj; end end methods (Static) function propValues(newObj,orgObj) pl = properties(orgObj); for k = 1:length(pl) if isprop(newObj,pl{k}) newObj.(pl{k}) = orgObj.(pl{k}); end end end end end
ColorProp
The ColorProp
class defines a color by assigning an RGB value to its Color
property.
classdef ColorProp < handle properties Color = 'blue'; end end
Exclude Properties from Copy
Use the NonCopyable
property attribute to indicate that you do not want a copy operation to copy a particular property value. By default, NonCopyable
is false
, indicating that the property value is copyable. You can set NonCopyable
to true
only on properties of handle classes.
For classes that derive from matlab.mixin.Copyable
, the default implementation of copyElement
honors the NonCopyable
attribute. Therefore, if a property has its NonCopyable
attribute set to true
, then copyElement
does not copy the value of that property. If you override copyElement
in your subclass, you can choose how to use the NonCopyable
attribute.
Set the Attribute to Not Copy
Set NonCopyable
to true
in a property block:
properties (NonCopyable) Prop1 end
Default Values
If a property that is not copyable has a default value assigned in the class definition, the copy operation assigns the default value to the property. For example, the CopiedClass
assigns a default value to Prop2
.
classdef CopiedClass < matlab.mixin.Copyable properties (NonCopyable) Prop1 Prop2 = datestr(now) % Assign current time end end
Create an object to copy and assign a value to Prop1
:
a = CopiedClass; a.Prop1 = 7
a = CopiedClass with properties: Prop1: 7 Prop2: '17-Feb-2015 15:19:34'
Copy a
to b
using the copy
method inherited from matlab.mixin.Copyable
:
b = copy(a)
b = CopiedClass with properties: Prop1: [] Prop2: '17-Feb-2015 15:19:34'
In the copy b
, the value of Prop1
is not copied. The value of Prop2
is set to its default value, which MATLAB® determined when first loading the class. The timestamp does not change.
Objects with Dynamic Properties
Subclasses of the dynamicprops
class allow you to add properties to an object of the class. When a class derived from dynamicprops
is also a subclass of matlab.mixin.Copyable
, the default implementation of copyElement
does not copy dynamic properties. The default value of NonCopyable
is true
for dynamic properties.
The default implementation of copyElement
honors the value of a dynamic property NonCopyable
attribute. If you want to allow copying of a dynamic property, set its NonCopyable
attribute to false
. Copying a dynamic property copies the property value and the values of the property attributes.
For example, this copy operation copies the dynamic property, DynoProp
, because its NonCopyable
attribute is set to false
. The object obj
must be an instance of a class that derives from both dynamicprops
and matlab.mixin.Copyable
:
obj = MyDynamicClass; p = addprop(obj,'DynoProp'); p.NonCopyable = false; obj2 = copy(obj);