Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
clone (deep copy) a handle object

Subject: clone (deep copy) a handle object

From: Guillaume Perrault Archambault

Date: 6 Aug, 2009 16:53:02

Message: 1 of 9

I need to make a deep copy of a hande object. Is there any easy way to do this in R2009a?

Subject: clone (deep copy) a handle object

From: Doug Schwarz

Date: 6 Aug, 2009 17:52:36

Message: 2 of 9

In article <h5f1pe$2ll$1@fred.mathworks.com>,
 "Guillaume Perrault Archambault" <guigui.the.bulldozer@gmail.com>
 wrote:

> I need to make a deep copy of a hande object. Is there any easy way to do
> this in R2009a?

When I had to do this I added this method to my class:

        % Make a copy of a handle object.
        function new = copy(this)
            % Instantiate new object of the same class.
            new = feval(class(this));
 
            % Copy all non-hidden properties.
            p = properties(this);
            for i = 1:length(p)
                new.(p{i}) = this.(p{i});
            end
        end


Then, when I want to make a copy of

  a = myclass;

I use something like this:

  b = copy(a); % which reads nicely as b = copy of a

or, equivalently,

  b = a.copy;


If you need to copy hidden properties which don't show up in the result
of properties(this), you can use

    p = fieldnames(struct(this));

instead.

--
Doug Schwarz
dmschwarz&ieee,org
Make obvious changes to get real email address.

Subject: clone (deep copy) a handle object

From: Guillaume Perrault Archambault

Date: 7 Aug, 2009 12:59:02

Message: 3 of 9

It's exactly what I needed. Thanks!
G

Doug Schwarz <see@sig.for.address.edu> wrote in message <see-CD8C71.13523606082009@news.frontiernet.net>...
> In article <h5f1pe$2ll$1@fred.mathworks.com>,
> "Guillaume Perrault Archambault" <guigui.the.bulldozer@gmail.com>
> wrote:
>
> > I need to make a deep copy of a hande object. Is there any easy way to do
> > this in R2009a?
>
> When I had to do this I added this method to my class:
>
> % Make a copy of a handle object.
> function new = copy(this)
> % Instantiate new object of the same class.
> new = feval(class(this));
>
> % Copy all non-hidden properties.
> p = properties(this);
> for i = 1:length(p)
> new.(p{i}) = this.(p{i});
> end
> end
>
>
> Then, when I want to make a copy of
>
> a = myclass;
>
> I use something like this:
>
> b = copy(a); % which reads nicely as b = copy of a
>
> or, equivalently,
>
> b = a.copy;
>
>
> If you need to copy hidden properties which don't show up in the result
> of properties(this), you can use
>
> p = fieldnames(struct(this));
>
> instead.
>
> --
> Doug Schwarz
> dmschwarz&ieee,org
> Make obvious changes to get real email address.

Subject: clone (deep copy) a handle object

From: Till Bockemuehl

Date: 30 Sep, 2009 15:29:33

Message: 4 of 9

Many thanks from me as well. Works like a charm!

Best regards,

Till

Subject: clone (deep copy) a handle object

From: Peter

Date: 20 Oct, 2009 08:49:01

Message: 5 of 9

The use of:
p = fieldnames(struct(this));
seems to work fine for public properties, but not for private and protected properties.

The function returns:
??? Getting the 'property_protected' property of the '...' class is not allowed.

Do you have a suggestion to make a deep copy of a hande object which also copies these properties?

Regards,
Peter

Doug Schwarz <see@sig.for.address.edu> wrote in message <see-CD8C71.13523606082009@news.frontiernet.net>...
> In article <h5f1pe$2ll$1@fred.mathworks.com>,
> "Guillaume Perrault Archambault" <guigui.the.bulldozer@gmail.com>
> wrote:
>
> > I need to make a deep copy of a hande object. Is there any easy way to do
> > this in R2009a?
>
> When I had to do this I added this method to my class:
>
> % Make a copy of a handle object.
> function new = copy(this)
> % Instantiate new object of the same class.
> new = feval(class(this));
>
> % Copy all non-hidden properties.
> p = properties(this);
> for i = 1:length(p)
> new.(p{i}) = this.(p{i});
> end
> end
>
>
> Then, when I want to make a copy of
>
> a = myclass;
>
> I use something like this:
>
> b = copy(a); % which reads nicely as b = copy of a
>
> or, equivalently,
>
> b = a.copy;
>
>
> If you need to copy hidden properties which don't show up in the result
> of properties(this), you can use
>
> p = fieldnames(struct(this));
>
> instead.
>
> --
> Doug Schwarz
> dmschwarz&ieee,org
> Make obvious changes to get real email address.

Subject: clone (deep copy) a handle object

From: Barry Ridge

Date: 3 Jun, 2010 13:34:04

Message: 6 of 9

"Guillaume Perrault Archambault" <guigui.the.bulldozer@gmail.com> wrote in message <h5f1pe$2ll$1@fred.mathworks.com>...
> I need to make a deep copy of a hande object. Is there any easy way to do this in R2009a?

I came up with a bit of a hack for doing this. It uses file-handling, and therefore is not so elegant, but it seems to work. Just add this method to whatever class you want to copy:

function new = copy(this)
            save('temp.mat', 'this');
            Foo = load('temp.mat');
            new = Foo.this;
            delete('temp.mat');
end

Example usage (assumes copy() is a method in class MyClass):
A = MyClass();
B = A.copy();

Subject: clone (deep copy) a handle object

From: Peter O'Connor

Date: 15 Dec, 2011 23:35:11

Message: 7 of 9

The above won't work if your properties are also handle objects (that is, your properties will still refer to the original objects). It also gets a little more complicated when you have circular object references (eg A.B.A==A) or objects that can be referenced from two different paths (eg A.B==A.C).

The below code takes care of these things. To use it, subclass your class of DataBaseObject instead of handle, then you can use the copy method (eg "B=A.copy"). I trimmed it down a bit for this post but I think it should work as-is.

Happy copying

===================================================

classdef DataBaseItem<handle
    % Contains a few properties and method useful when dealing with arrays
    % of linked objects like one would in a relational database.
    %
    %
    
    properties
       
        copyCode; % This code ensures that when doing a deep copy, objects
                    % With cyclic references aren't copied in infinite
                    % loops.
                            
        copies=struct; % Links to next copies.
                    
    end
    
    methods
        
        function B=copy(A,Ob,copyCode)
            % Make a deep copy of the object. The copyCode stuff is there
            % to make sure circular references don't get copied in infinite
            % loops
            %
            % Peter O'Connor
            
            if ~exist('Ob','var'), Ob=A; end
            
            % If object's already been copied
            if ~exist('copyCode','var'),
                copyCode=['c' num2str(typecast(now,'uint64'))];
                
            elseif ismember('DataBaseItem',superclasses(Ob))
                if isfield(Ob.copies,copyCode), % If it's been copied already, return the copy
                    B=Ob.copies.(copyCode);
                    return;
                end
            end
            
            meta=metaclass(Ob);
            pnames=cellfun(@(x)x.Name,meta.Properties,'uniformoutput',false);

            B=eval(class(Ob));
            warning off MATLAB:structOnObject
            S=struct(Ob);
            warning on MATLAB:structOnObject
            pB=fields(S);
            
            Ob.copies.(copyCode)=B;
            B.copyCode=copyCode;
            
            for i=1:length(pB)

                if any(ismember(pB{i},{'copies','copyCode'})), continue; end
                
                whichone=strcmp(pB{i},pnames);

                % Do not copy Transient or Dependent Properties
                if any(whichone) && (meta.Properties{whichone}.Transient || meta.Properties{whichone}.Dependent)
                    continue;
                end

                val=S.(pB{i});

                if ~isempty(val) && isa(val,'handle')
                    B.(pB{i})=eval(class(val));
                    B.(pB{i})(length(val))=eval(class(val)); % God damn ugly matlab
                    for j=1:length(val)
                        B.(pB{i})(j)=A.copy(val(j),copyCode);
                    end
                else
                    B.(pB{i})=val;
                end
            end
            
        end
end

===================================================

Subject: clone (deep copy) a handle object

From: Peter O'Connor

Date: 16 Dec, 2011 00:14:08

Message: 8 of 9

Actually minor edit: replace

copyCode=['c' num2str(typecast(now,'uint64'))];
with
copyCode=['c' num2str(typecast(rand,'uint64'))];

Because if you're copying things in quick succession, "now" won't give a unique answer

Subject: clone (deep copy) a handle object

From: Mark Mikofski

Date: 17 Dec, 2012 18:04:06

Message: 9 of 9

"Peter O'Connor" <peter.oconnor@mail.mcgill.ca> wrote in message <jce2gg$3sv$1@newscl01ah.mathworks.com>...
> Actually minor edit: replace
>
> copyCode=['c' num2str(typecast(now,'uint64'))];
> with
> copyCode=['c' num2str(typecast(rand,'uint64'))];
>
> Because if you're copying things in quick succession, "now" won't give a unique answer

For those consulting this thread in the present (2012), it looks like this has been implemented in MATLAB at least as early as R2012a (and possibly earlier).

Subclass your object to matlab.mixin.Copyable instead of handle and that will expose the copy method which will perform shallow copies (no dependent or nested objects or recursive properties).

The methods can be overloaded and an example is given for a method to make deep copies.

http://www.mathworks.com/help/releases/R2012a/techdoc/ref/matlab.mixin.copyableclass.html

http://www.mathworks.com/help/releases/R2012a/techdoc/ref/matlab.mixin.copyable.copy.html

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us