digitalmars.D.learn - clone method of Object
- Qian Xu (3/3) Apr 15 2009 Hi All,
- grauzone (14/20) Apr 15 2009 Simple answer: No.
- grauzone (9/34) Apr 15 2009 I should add that members of subclasses are not copied either. E.g. if
- bearophile (4/5) Apr 15 2009 A *good* implementation of this function seems fit to be added to Phobos...
- grauzone (2/8) Apr 15 2009
- Qian Xu (14/15) Apr 15 2009 If the current value of tupleof[i] is an object, the object will be
- grauzone (16/37) Apr 15 2009 Object graphs often contain circular references liker this:
- Qian Xu (2/20) Apr 15 2009 You are right. This case must be considered separately.
- Qian Xu (58/60) Apr 15 2009 Hi again.
- grauzone (4/7) Apr 15 2009 It was changed in dmd later, and now you can access private attributes
- jDavidls (8/8) Sep 20 2009 This works very well (GDC 4.2.4):
Hi All, is there any (easy) way to clone an object or any other classes? --Qian
Apr 15 2009
Qian Xu wrote:Hi All, is there any (easy) way to clone an object or any other classes? --QianSimple answer: No. Complicated answer: Yes, but you have to write it yourself. Here's a nice starting point. You can use tupleof to get all members of a class. Note that this doesn't deal with superclasses, and members of superclasses are not copied: T clone(T)(T old) { auto newobject = new T(); foreach (int i, _; old.tupleof) { newobject.tupleof[i] = old.tupleof[i]; } return newobject; } cloned = clone(yourobject);
Apr 15 2009
grauzone wrote:Qian Xu wrote:I should add that members of subclasses are not copied either. E.g. if you have class A {int a;} class B : A {int b;} class C : B {int c;} B someobject; clone(someobject); the clone method will only copy member b, but not a or c.Hi All, is there any (easy) way to clone an object or any other classes? --QianSimple answer: No. Complicated answer: Yes, but you have to write it yourself. Here's a nice starting point. You can use tupleof to get all members of a class. Note that this doesn't deal with superclasses, and members of superclasses are not copied: T clone(T)(T old) { auto newobject = new T(); foreach (int i, _; old.tupleof) { newobject.tupleof[i] = old.tupleof[i]; } return newobject; } cloned = clone(yourobject);
Apr 15 2009
grauzone:the clone method will only copy member b, but not a or c.A *good* implementation of this function seems fit to be added to Phobos. Bye, bearophile
Apr 15 2009
bearophile wrote:grauzone:And serialization, and a complete reflection API.the clone method will only copy member b, but not a or c.A *good* implementation of this function seems fit to be added to Phobos.Bye, bearophile
Apr 15 2009
grauzone wrote:newobject.tupleof[i] = old.tupleof[i];If the current value of tupleof[i] is an object, the object will be referenced, won't it? Shall I write: auto elem = old.tupleof[i]; static if (is(typeof(elem) == class)) { newobject.tupleof[i] = clone(elem); } else { newobject.tupleof[i] = elem; } --Qian
Apr 15 2009
Qian Xu wrote:grauzone wrote:Object graphs often contain circular references liker this: class A { B b; } class B { A a; } auto a = new A(); auto b = new B(); a.b = b; b.a = a; Your recursive approach wouldn't quite work with that. Before cloning an object, you'll first have to check if the object was already cloned. If this is the case, use the previously created clone instead of making a new clone.newobject.tupleof[i] = old.tupleof[i];If the current value of tupleof[i] is an object, the object will be referenced, won't it? Shall I write: auto elem = old.tupleof[i]; static if (is(typeof(elem) == class)) { newobject.tupleof[i] = clone(elem); } else { newobject.tupleof[i] = elem; }--Qian
Apr 15 2009
grauzone wrote:class A { B b; } class B { A a; } auto a = new A(); auto b = new B(); a.b = b; b.a = a; Your recursive approach wouldn't quite work with that. Before cloning an object, you'll first have to check if the object was already cloned. If this is the case, use the previously created clone instead of making a new clone.You are right. This case must be considered separately.
Apr 15 2009
grauzone wrote:... cloned = clone(yourobject);Hi again. There are two things on my side: 1. Compiler refuses to clone private attributes. I have tried gdc/gdmd/dmd_v1 in Linux. 2. I have implemented an example. But some part not implemented. ----------------- code ----------------------- T clone(T)(T oldobj) { auto newobj = new T(); if (oldobj is null) { return newobj; } foreach (int i, _; oldobj.tupleof) { auto elem = oldobj.tupleof[i]; static if (is(typeof(elem): char[]*)) {/* if (elem !is null) { char[] tmp; tmp = (*elem).dup; newobj.tupleof[i] = &tmp; } else { newobj.tupleof[i] = null; }*/ NotImplemented_PleaseHelpMe; } else static if (is(typeof(elem) T2 : T2*)) { if (elem !is null) { newobj.tupleof[i] = new T2; *newobj.tupleof[i] = *elem; } else { newobj.tupleof[i] = null; } } else static if (is(typeof(elem) == class)) { if (elem !is null) { newobj.tupleof[i] = clone(elem); } else { newobj.tupleof[i] = null; } } else { newobj.tupleof[i] = elem; } } return newobj; } ----------------- code -----------------------
Apr 15 2009
There are two things on my side: 1. Compiler refuses to clone private attributes. I have tried gdc/gdmd/dmd_v1 in Linux.It was changed in dmd later, and now you can access private attributes by using tupleof. I don't know when exactly it was changed, but it should work at least with dmd 1.039 and later. GDC probably uses an ancient front-end version, and I think nobody should use it.
Apr 15 2009
This works very well (GDC 4.2.4): Object clone(Object object) { auto size = object.classinfo.init.length; object = cast(Object) ( (cast(void*)object) [0..size].dup.ptr ); // object.__monitor = null; return object; }
Sep 20 2009