Am Thu, 20 Sep 2012 12:06:28 +0200 schrieb "monarch_dodra" <monarchdo...@gmail.com>:
> On Thursday, 20 September 2012 at 08:10:36 UTC, Namespace wrote: > > You're right. > > This is my next try: http://dpaste.dzfl.pl/02b32d33 > > Do you have anything else to say? :) > > I think it looks good, but I'm unsure about "move", or allowing > pass by value: > > Classes can't be memcopied the way structs can: Class may have > default constructors, or copy constructors, which would be > totally ignored by a memcopy. For example, if your class had a > "RefCounted" member, its postblit would never be called, and it > would then be "over destroyed": > > -------- > class A > { > RefCounted!int rf; > this() > { > rf.RefCounted.ensureInitialized(); > rf = 5; > } > } > > void main() > { > A a = new A(); > OnStack!A osa = OnStack!A.move(a); > } > -------- > core.exception.InvalidMemoryOperationError > -------- > Here, osa makes a binary copy of the RefCounted, so the count > stays at 1. > Then, when osa is destroyed, it deletes the RefCounted's store. > However, when a is destroyed, it still has a pointer to the > (deleted) store, creating the Error... > > I think "move" has to go, because classes are just not moveable. > pass by value can stay, if and only if, T gives a copy > constructor. Or NO constructors (in which case a memcopy should > be the same as a default copy). http://dlang.org/struct.html D classes do not really have copy constructors. You could assume that if a constructor has only one argument and it's of the same type as the class, it's a copy constructor. But that's a pure convention then, nothing than could be enforced in any way. Copying classes is dangerous, and problems can also happen without constructors: ---------- class A { void* handle; ~this() { if(handle) free(handle); } } { auto a = OnStack!A(); a.handle = someHandle; auto b = a; //copy } //end of scope, someHandle is freed twice ---------- This can even happen if the class does not keep any reference types. The example would also be valid with a file handle (uint).