Taking a copy of an object

Kirk McDonald kirklin.mcdonald at gmail.com
Thu Aug 3 23:19:23 PDT 2006


Derek Parnell wrote:
> On Thu, 03 Aug 2006 16:28:25 -0700, Kirk McDonald wrote:
> 
> 
>>People used to C++ are used to doing this with an operator overload. 
>>People used to some other languages (e.g. Python) will be more used to 
>>using a method (or even a library function, in the case of Python). I 
>>honestly don't think it matters.
>>
>>One could also argue for the use of copy constructors, of course. This 
>>may be getting too close to C++ for some people's tastes, though. (The 
>>syntax is also more verbose than a simple .dup property.)
> 
> 
> Copy constructors and 'standard' functions would have to work with basic
> types, structs and arrays too for it to be really useful.
> 

Of course. :-)

>  
> 
>>class Foo {
>>     int m_i;
>>     this(int i) { m_i = i; }
>>     this(Foo f) { m_i = f.m_i; }
>>}
>>
>>Foo a, b;
>>a = new Foo(20);
>>b = new Foo(a);
>>
>>This does have the advantage of using "new" to make it clear that we are 
>>allocating a new object (though I don't think this is really a problem 
>>with just using .dup).
>>
>>With reflection support, we could even give Object a useful default copy 
>>constructor, as Tom S pointed out.
> 
> 
> Not everything is an object. <g>
> 
>   template backup(T)
>   {
>       void backup(inout T[] st, T dt)
>       {
>            st.length = st.length + 1;
>            st[$-1] := dt;  // Invokes opDup for classes and structs,
>                            // .dup for arrays,
>                            // binary copy for everything else
>       }
>   }
> 
>   int[] istore;
>   backup( istore, anInt);
> 
>   Foo[] foostore;
>   backup( foostore, aFoo);
>  
> 

opDup appeals to me, but more consistent would probably be a standard 
.dup property. Despite what others have said, := is not a terrible 
operator. However, having := be overloaded with a "dup" function instead 
of an "opDup" function is inconsistent with the other operator overloads.

So let's get the problem clear before we go proposing solutions: We want 
a standard way of getting a copy of an object. We can either use an 
operator for this purpose (such as :=), or a standard method (such as 
.dup, as arrays currently use for the same purpose).

The := operator should work for classes, structs, arrays, and other 
primitive types. Arrays already have the .dup property, so := can use 
that. Remember that structs use value semantics. Assigning a struct the 
normal way copies its members. So, for structs and the various primitive 
types (that is to say, all of the types that use value semantics), := 
will be identical to a regular assignment.

I suggest a copy constructor as a way of overloading := for class 
objects. This is a C++ thing, but it is actually a fairly elegant 
solution, I think.

The complication, now, is getting a constant way of getting a copy of 
some object or value when we don't actually want to assign it to 
anything (say, in a function call). My initial thought is to use unary : 
to mean "copy-of" (this is consistent with the := operator), but (not 
knowing much about how the parser works), I can't help but think that 
this might interfere with labels or the trinary ?: operator or 
something. Someone care to comment on that? The syntax looks fine:

fn( i, j, :obj); // send a copy of obj to the function

So, for both the proposed := copy-assignment operator and unary : copy 
operator, the various copying mechanisms would be:

class instances:                copy constructor
arrays/AAs:                     dup property
structs, primitive types, etc:  by-value copy

We wouldn't even have to provide a copy constructor in Object, you know. 
Trying to use these operators on an instance of a class that doesn't 
define a copy constructor would just be a compiler error, like any other 
undefined operator overload or method you try to use.

Thoughts?

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://dsource.org/projects/pyd/wiki



More information about the Digitalmars-d mailing list