Taking a copy of an object

Kirk McDonald kirklin.mcdonald at gmail.com
Fri Aug 4 00:26:19 PDT 2006


Derek Parnell wrote:
> On Thu, 03 Aug 2006 23:19:23 -0700, Kirk McDonald wrote:
>>So let's get the problem clear before we go proposing solutions: We want 
>>a standard way of getting a copy of an object. 
> 
> 
> Rather than using the term 'object' here, let's use the term 'item' because
> it is not so ambiguous. In this way, 'item' can mean every data type
> supported by D.
> 
> 

"Item" it is!

>>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.
> 
> 
> Hmmm... not so certain about that. A shallow copy (bit-by-bit) is already
> performed by .dup and struct assignment, but we need a neat way to express
> that we want a deep copy done. That is, we want the information copied and
> not just the bits in the source item. Such that if an item contains
> references (dynamic arrays, objects, and other pointers) it might want to
> take copies of all their contents too. 
> 
>   char[][] theFile;
>   char[][] backup;
>   . . .
>   backup := theFile;  // Make a copy of all the strings, not just
>                       // the references to the strings.
> 
>   class Foo
>   {
>       Bar b;
>   }
> 
>   Foo a := aFoo;  // Takes a copy of the Foo object *and* the 
>                   // contained Bar object, not just a copy of
>                   // the reference to the Bar object.
> 
> 

Do we want this to mean a deep copy? The only distinction we (I?) have 
been talking in terms of is the simple case, so I guess it hasn't been 
addressed, yet.

Python, for the record, allows classes to define both a __copy__ and a 
__deepcopy__ method (the double-underscores are Python's standard 
notation for operator overloading), and provides both a copy() and a 
deepcopy() library function. If a class doesn't provide a __copy__ or 
__deepcopy__ method, the library functions will use Python's 
introspective capabilities and do a naive copy or deep copy. (This is 
usually adequate.)

I am rapidly thinking that an operator is a bad idea. Please disregard 
my earlier musings on the idea. :-)

So! Define .dup to mean a shallow copy for classes. Object should not 
provide it. Classes that want to provide it, can. (This happily requires 
zero changes to the language! Hooray!) For consistency's sake, dup 
should be provided for primitive types. (This may simplify template 
code.) Structs should provide it as a bit-by-bit copy, just like regular 
assignment does now. I am split on whether users should be able to 
overload it for structs. I can't think of a good reason why one /would/ 
overload it, but then I can't think of a good, specific reason to 
disallow it, either.

A second standard property should be provided for deep copying. I 
suggest "deepcopy". As with 'dup', classes can provide this or not. 
Attempting to deepcopy an array of a class that doesn't provide a 
deepcopy property, or a struct containing such a class, should be a 
compile error. As with .dup, it should be provided for primitive types 
as an aid for template code.

If it is really wanted, := can be provided as a shortcut for assigning 
to a deepcopy. However (as I pointed out earlier) this would be 
inconsistent with the other operator overload names, and so I don't 
think it's really a good idea.

Using a copy constructor for either of these is probably not a good 
idea, as it doesn't imply anything about whether the copy is shallow or 
deep. (Naturally, classes can still provide one for their own nefarious 
purposes.)

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



More information about the Digitalmars-d mailing list