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