Jump to page: 1 2
Thread overview
How to copy an object?
Aug 20, 2005
Chuck Esterbrook
Aug 20, 2005
Manfred Nowak
Aug 20, 2005
Chuck Esterbrook
Aug 20, 2005
Ben Hinkle
Aug 20, 2005
Chuck Esterbrook
Aug 20, 2005
Burton Radons
Aug 20, 2005
Chris Sauls
Aug 20, 2005
Burton Radons
Aug 20, 2005
Burton Radons
Aug 20, 2005
Ben Hinkle
Aug 21, 2005
Chuck Esterbrook
Aug 21, 2005
Ben Hinkle
Aug 21, 2005
Chuck Esterbrook
August 20, 2005
I want a shallow copy of an object. Something like:

# Object obj = someOtherObj.copy;

where I could assert afterwards that:
- obj !is someOtherObj
- they have the same class
- their data members are identical

In C# this is called MemberwiseClone (although it's protected so you have to wrap it with a public method).

In Python, this is done with the copy module.

Is there something analagous in D? (I searched for "copy" and "clone" in various places like this newsgroup, the Phobos docs and Wiki4D, but didn't catch anything.)


Thanks,
-Chuck
August 20, 2005
Chuck Esterbrook <Chuck.Esterbrook@gmail.antispam.com> wrote:

> I want a shallow copy of an object.
[...]

Please read the FAQ:

Why is overload the assignment operator not supported?

-manfred
August 20, 2005
On Sat, 20 Aug 2005 05:26:49 +0000 (UTC), Manfred Nowak
<svv1999@hotmail.com> wrote:

>Chuck Esterbrook <Chuck.Esterbrook@gmail.antispam.com> wrote:
>
>> I want a shallow copy of an object.
>[...]
>
>Please read the FAQ:
>
>Why is overload the assignment operator not supported?
>
>-manfred

I assume you're referring to: "Sometimes, one does need to create a copy of a class object, and for that one can still write a copy constructor in D" ...as I'm not wanting to redefine =.

Let me clarify my question:

Is there a general purpose function that is written, or could be written, to take any obj ref and return a copy of it?

Something like:

Object copy(Object obj) {
    Object newObj;
    <insert magic here>;
    return newObj;
}

Maybe it would even be something like:

Object copy(Object obj) {
    if (obj is null)
        return null;
    int* newObj = cast(int*)malloc(SIZEOF?(obj));
    memcpy(newObj, (int*)obj, SIZEOF?(obj));
    return cast(Object)newObj;
}

Or maybe those should be "void*" instead of "int*" above. Also, I don't know how to get the size of any arbitrary object.

-Chuck
August 20, 2005
"Chuck Esterbrook" <Chuck.Esterbrook@gmail.antispam.com> wrote in message news:ji7eg1h3sagap5atgtmufu4uinc6q1kll2@4ax.com...
> On Sat, 20 Aug 2005 05:26:49 +0000 (UTC), Manfred Nowak
> <svv1999@hotmail.com> wrote:
>
>>Chuck Esterbrook <Chuck.Esterbrook@gmail.antispam.com> wrote:
>>
>>> I want a shallow copy of an object.
>>[...]
>>
>>Please read the FAQ:
>>
>>Why is overload the assignment operator not supported?
>>
>>-manfred
>
> I assume you're referring to: "Sometimes, one does need to create a copy of a class object, and for that one can still write a copy constructor in D" ...as I'm not wanting to redefine =.
>
> Let me clarify my question:
>
> Is there a general purpose function that is written, or could be written, to take any obj ref and return a copy of it?

Nope. If a class authors wants a class to be copyable they need to write either a dup() property or a copy constructor. Technically they can write whatever function they want but dup() is the standard name for the "duplicate" method. What are you trying to do?

> Something like:
>
> Object copy(Object obj) {
>    Object newObj;
>    <insert magic here>;
>    return newObj;
> }
>
> Maybe it would even be something like:
>
> Object copy(Object obj) {
>    if (obj is null)
>        return null;
>    int* newObj = cast(int*)malloc(SIZEOF?(obj));
>    memcpy(newObj, (int*)obj, SIZEOF?(obj));
>    return cast(Object)newObj;
> }
>
> Or maybe those should be "void*" instead of "int*" above. Also, I don't know how to get the size of any arbitrary object.
>
> -Chuck


August 20, 2005
"Chuck Esterbrook" <Chuck.Esterbrook@gmail.antispam.com> wrote in message news:ji7eg1h3sagap5atgtmufu4uinc6q1kll2@4ax.com...
> Or maybe those should be "void*" instead of "int*" above. Also, I don't know how to get the size of any arbitrary object.

It's typename.sizeof in D.  Like int.sizeof or MyClass.sizeof.


August 20, 2005
On Sat, 20 Aug 2005 08:46:59 -0400, "Ben Hinkle" <ben.hinkle@gmail.com> wrote:
>"Chuck Esterbrook" <Chuck.Esterbrook@gmail.antispam.com> wrote in message
[snip]
>> Is there a general purpose function that is written, or could be written, to take any obj ref and return a copy of it?
>
>Nope. If a class authors wants a class to be copyable they need to write either a dup() property or a copy constructor. Technically they can write whatever function they want but dup() is the standard name for the "duplicate" method. What are you trying to do?

It would be nice to have this feature to reduce maintenance so that if I add a member var "int _foo;" I don't get burned by forgetting to update dup().

Also, I'm exploring the language and I'm used to having a "shallow copy" function in languages such as C#, Python and Smalltalk. So it's one of those things I happen to look for.

Thanks for the reply,

-Chuck
August 20, 2005
Chuck Esterbrook wrote:

> I want a shallow copy of an object. Something like:
> 
> # Object obj = someOtherObj.copy;
> 
> where I could assert afterwards that:
> - obj !is someOtherObj
> - they have the same class
> - their data members are identical
> 
> In C# this is called MemberwiseClone (although it's protected so you
> have to wrap it with a public method).
> 
> In Python, this is done with the copy module.
> 
> Is there something analagous in D? (I searched for "copy" and "clone"
> in various places like this newsgroup, the Phobos docs and Wiki4D, but
> didn't catch anything.)

    extern (C) Object _d_newclass (ClassInfo info);

    template shallow_copy (T : Object)
    {
        T shallow_copy (T value)
        {
            if (value is null)
                return null;

            void *copy = _d_newclass (value.classinfo);
            size_t size = value.classinfo.init.length;

            copy [0 .. size] = (cast (void *) value) [0 .. size];
            return cast (T) copy;
        }
    }

:Q
August 20, 2005
Haha, why'd I put that in a template?  It just hides the cast.  That should be:

    private extern (C) Object _d_newclass (ClassInfo info);

    Object shallow_copy (Object value)
    {
        if (value is null)
            return null;

        void *copy = _d_newclass (value.classinfo);
        size_t size = value.classinfo.init.length;

        copy [8 .. size] = (cast (void *) value) [8 .. size];
        return cast (Object) copy;
    }

Better to start at that offset to avoid copying the synchronisation handle over, plus it's pointless work.
August 20, 2005
Jarrett Billingsley wrote:

> "Chuck Esterbrook" <Chuck.Esterbrook@gmail.antispam.com> wrote in message news:ji7eg1h3sagap5atgtmufu4uinc6q1kll2@4ax.com...
> 
>>Or maybe those should be "void*" instead of "int*" above. Also, I
>>don't know how to get the size of any arbitrary object.
> 
> 
> It's typename.sizeof in D.  Like int.sizeof or MyClass.sizeof. 

sizeof returns the size of the value on the stack, so a class's sizeof is always 4.
August 20, 2005
Burton Radons wrote:
> Jarrett Billingsley wrote:
> 
>> "Chuck Esterbrook" <Chuck.Esterbrook@gmail.antispam.com> wrote in message news:ji7eg1h3sagap5atgtmufu4uinc6q1kll2@4ax.com...
>>
>>> Or maybe those should be "void*" instead of "int*" above. Also, I
>>> don't know how to get the size of any arbitrary object.
>>
>>
>>
>> It's typename.sizeof in D.  Like int.sizeof or MyClass.sizeof. 
> 
> 
> sizeof returns the size of the value on the stack, so a class's sizeof is always 4.

Would .classinfo.init.size work?

-- Chris Sauls
« First   ‹ Prev
1 2