www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Class copy

reply Satoshi <satoshi gshost.eu> writes:
Hello,
how can I copy class when I have pointer to the parent of it?

eg.

class Foo {
     int m_a;

     this(const(Foo) other) {
         m_a = other.m_a;
     }
}

class Bar : Foo {
     int m_b;

     this(const(Bar) other) {
         super(other);

         m_b = other.m_b;
     }

     R dup(this R)() {
         void* data = cast(void *)typeid(this).create();
         data[0 .. __traits(classInstanceSize, R)] = 
typeid(R).init[];

         auto ret = cast(R)data;
         ret.__ctor(this);

         return ret;
     }
}



Foo foo = new Bar;

Foo copyOfFoo = foo.dup; // ??


But this implementation of dup doesn't work.
Thanks
Nov 10 2016
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 10 November 2016 at 16:44:24 UTC, Satoshi wrote:
 But this implementation of dup doesn't work.
The dup will need to be a virtual function in the base class for best results, reimplemented in each child class. You could also copy the bytes using runtime type info... void* data = cast(void *)typeid(this).create(); data[0 .. __traits(classInstanceSize, R)] = typeid(R).init[]; auto ret = cast(R)data; The first line there uses the runtime info, but the other two use the static type (this template parameters still use the static type just at the usage point instead of inside the class. So here, it is the base class since the static type of `Foo foo = new Bar;` is Foo.) Instead, you can change that second line to be something like: data[0 .. typeid(this).initializer.length] = (cast(void*)this)[0 .. typeid(this).initializer.length]; or something along those lines - the typeid(this) is the key factor instead of __traits so it uses the runtime info. The initializer.length should be the same as the class instance size. ... I think.
Nov 10 2016