Copy constructor question.

Discussion in 'C++' started by Vinesh S, Sep 27, 2011.

  1. Vinesh S

    Vinesh S Guest

    Hello All,

    i have a question with copy construction here.

    i have for example


    class A // abstract base class
    {
    ....
    }

    class B : public A
    {
    ....
    }

    class C : public A
    {
    ....
    }

    also i have totally an unrelated class called D.


    class D
    {
    D(A* basepointer , int k, int y) // constructor
    {
    ....
    basePtr = basePointer;
    }


    private
    A* basePtr
    }

    QUESTION:
    how do i write a copy constructor for Class D?

    1. problem i face is : if am not allowed to use memcpy ...
    .... i need to copy the value pointed by the basePtr in the copy
    constructor to the resulting class.
    but i dont know what instance it holds ( whether class b or class
    c ) to allocate memory and copy it

    Looking forward to hear from you all,


    Vinesh.S
    Vinesh S, Sep 27, 2011
    #1
    1. Advertising

  2. On 9/27/2011 3:28 PM, Vinesh S wrote:
    > Hello All,
    >
    > i have a question with copy construction here.
    >
    > i have for example
    >
    >
    > class A // abstract base class
    > {
    > ...
    > }

    ;
    >
    > class B : public A
    > {
    > ...
    > }

    ;
    >
    > class C : public A
    > {
    > ...
    > }

    ;
    >
    > also i have totally an unrelated class called D.
    >
    >
    > class D
    > {
    > D(A* basepointer , int k, int y) // constructor
    > {
    > ....
    > basePtr = basePointer;


    basePtr = basepointer;

    > }
    >
    >
    > private

    :

    > A* basePtr


    ;
    > }

    ;
    >
    > QUESTION:
    > how do i write a copy constructor for Class D?


    From what I can understand given the microscopic amount of code you
    posted, there is no need for you to implemented your own copy c-tor for
    'D'. Your 'D' does not seem to own the memory behind 'basePtr', and as
    such should just copy the pointer instead of trying to copy the object
    that the 'basePtr' actually points to.

    > 1. problem i face is : if am not allowed to use memcpy ...


    I don't see any problem. Why do you think it's a problem?

    > ... i need to copy the value pointed by the basePtr in the copy
    > constructor to the resulting class.


    The compiler will copy it for you. Or you can copy the pointer if you'd
    like:

    D(const D& otherD) : basePtr(otherD.basePtr) {}

    > but i dont know what instance it holds ( whether class b or class
    > c ) to allocate memory and copy it


    There seems to be no need to know.

    > Looking forward to hear from you all,


    Don't hold your breath.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 27, 2011
    #2
    1. Advertising

  3. Vinesh S

    Goran Guest

    On Sep 27, 9:28 pm, Vinesh S <> wrote:
    > Hello All,
    >
    > i have a question with copy construction here.
    >
    > i have for example
    >
    > class A // abstract base class
    > {
    > ...
    >
    > }
    >
    > class B : public A
    > {
    > ...
    >
    > }
    >
    > class C : public A
    > {
    > ...
    >
    > }
    >
    > also i have totally an unrelated class called  D.
    >
    > class D
    > {
    >   D(A* basepointer , int k, int y)  // constructor
    >  {
    >     ....
    >      basePtr = basePointer;
    >  }
    >
    > private
    >     A* basePtr
    >
    > }
    >
    > QUESTION:
    > how do i write a copy constructor for Class D?
    >
    > 1. problem i face is  : if am not allowed to use memcpy ...
    > ... i need to copy the value pointed  by the basePtr in the copy
    > constructor to the resulting class.
    >     but i dont know what instance it holds ( whether class b or class
    > c ) to allocate memory and copy it


    You are of course absolutely not allowed to use memcpy to copy non-POD
    types. I hope you understand why.

    Since you are mentioning memcpy, for your copy of D, I guess you want
    a copy of basePtr. If so, you will need to clone it, e.g. like Paavo
    said. If not, you might take a look at shared_ptr class, which allows
    you to... well, "share" an object on the heap in various places.

    BTW, guys, it's the second cloning question in a couple of days here.

    Goran.
    Goran, Sep 28, 2011
    #3
  4. Vinesh S

    Vinesh S Guest

    On Sep 28, 2:08 am, Goran <> wrote:
    > On Sep 27, 9:28 pm, Vinesh S <> wrote:
    >
    >
    >
    > > Hello All,

    >
    > > i have a question with copy construction here.

    >
    > > i have for example

    >
    > > class A // abstract base class
    > > {
    > > ...

    >
    > > }

    >
    > > class B : public A
    > > {
    > > ...

    >
    > > }

    >
    > > class C : public A
    > > {
    > > ...

    >
    > > }

    >
    > > also i have totally an unrelated class called  D.

    >
    > > class D
    > > {
    > >   D(A* basepointer , int k, int y)  // constructor
    > >  {
    > >     ....
    > >      basePtr = basePointer;
    > >  }

    >
    > > private
    > >     A* basePtr

    >
    > > }

    >
    > > QUESTION:
    > > how do i write a copy constructor for Class D?

    >
    > > 1. problem i face is  : if am not allowed to use memcpy ...
    > > ... i need to copy the value pointed  by the basePtr in the copy
    > > constructor to the resulting class.
    > >     but i dont know what instance it holds ( whether class b or class
    > > c ) to allocate memory and copy it

    >
    > You are of course absolutely not allowed to use memcpy to copy non-POD
    > types. I hope you understand why.
    >
    > Since you are mentioning memcpy, for your copy of D, I guess you want
    > a copy of basePtr. If so, you will need to clone it, e.g. like Paavo
    > said. If not, you might take a look at shared_ptr class, which allows
    > you to... well, "share" an object on the heap in various places.
    >
    > BTW, guys, it's the second cloning question in a couple of days here.
    >
    > Goran.


    Thanks a lot for taking time to post your answers guys,

    Goran,

    The reason am not supposed to use memcpy is ... it would just copy the
    size of the basepointer but memory region associated to derived
    classes wouldnt be copied ... rite ???

    Yes, after posting here i researched some more and did find quite a
    few articles on cloning.

    Thanks again, for your responses y'all.

    This Group Rocks!!!

    Vinesh.S
    Vinesh S, Sep 28, 2011
    #4
  5. Goran <> wrote:
    > You are of course absolutely not allowed to use memcpy to copy non-POD
    > types. I hope you understand why.


    Suppose that rather than copy the objects you want to *move* them from
    one memory location to another, without invoking any constructors or
    destructors. A practical example where you may want to do this is in the
    implementation of std::vector (when the memory block allocated by it is
    reallocated): In this case you simply want to move the raw data from one
    place to another. You could use memcpy for this.

    However, is this a valid technique? Are there any hidden traps in doing
    this?
    Juha Nieminen, Sep 28, 2011
    #5
  6. On Sep 28, 1:39 am, Juha Nieminen <> wrote:
    > Goran <> wrote:
    > > You are of course absolutely not allowed to use memcpy to copy non-POD
    > > types. I hope you understand why.

    >
    >   Suppose that rather than copy the objects you want to *move* them from
    > one memory location to another, without invoking any constructors or
    > destructors. A practical example where you may want to do this is in the
    > implementation of std::vector (when the memory block allocated by it is
    > reallocated): In this case you simply want to move the raw data from one
    > place to another. You could use memcpy for this.
    >
    >   However, is this a valid technique? Are there any hidden traps in doing
    > this?


    Well, last time I tried this, my compiler literally shoved my laptop
    up my anus when he saw what I was attempting, so you tell me, Juha;
    you tell me.
    Oliver Jackson, Sep 28, 2011
    #6
  7. Vinesh S

    SG Guest

    On 27 Sep., 21:28, Vinesh S wrote:
    >
    > i have for example
    >
    > class A // abstract base class
    > {
    > ...
    > };
    >
    > class B : public A
    > {
    > ...
    > };
    >
    > class C : public A
    > {
    > ...
    > };
    >
    > also i have totally an unrelated class called  D.
    >
    > class D
    > {
    >   D(A* basepointer , int k, int y)  // constructor
    >  {
    >     ....
    >      basePtr = basePointer;
    >   }
    > private:
    >   A* basePtr;
    > };
    >
    > QUESTION:
    > how do i write a copy constructor for Class D?


    That depends on the behaviour you want in this situation. So far, you
    did not say what the semantics of a D-object is and what kind of
    relationship exists between D and A. Depending on what you want, you
    might not even have to write a copy constructor at all.

    There are at least three possible object<->object relationships:

    (1) object x is part / is a real member (subobject) of object y

    (2) object x is a logical part/member of object y but this is
    implemented with a pointer for some reason (possible reasons:
    polymorphism, optional member/nullable, variable number of
    members (see vector), ...)

    (3) object x is simply known by object y but neither physically
    nor logically "part" of object y. Typically, this is
    implemented with a pointer to x as member in y.

    Only in the second case the compiler-generated copy operations would
    do the wrong thing. So, in ths case you would have to define your own
    copy operations to get the semantics you want (like calling a clone
    function or something like this). There's maybe a fourth case: "1.5"
    where ownership of x is shared among a couple of objects like y (via
    shared_ptr, for example). Prefer (1) over (2) if possible. This saves
    you the hassle of writing your own copy operations and your own
    destructor.

    > 1. problem i face is  : if am not allowed to use memcpy ...
    > ... i need to copy the value pointed  by the basePtr in the copy
    > constructor to the resulting class.


    Sounds like case (2). I suggest adding a clone function to A:

    class A { // abstract base class
    public:
    virtual A~() {}
    virtual A* clone() const = 0;
    ...
    };

    This way you can simply invoke a clone function in D's copy-ctor:

    D::D(D const& x)
    : baseptr(x.baseptr->clone())
    {}

    In case baseptr==nullptr is part of the D class' invariant, you should
    add a null pointer test in there:

    D::D(D const& x)
    : baseptr(x.baseptr ? x.baseptr->clone() : 0)
    {}

    If you need this pattern a lot, it might be a good idea to generalize
    this and to write your own cloning smart pointer, so that the
    definition of D reduces to

    class D {
    public:
    explicit D(A* ptr) : ptr(ptr_) {}
    private:
    clone_ptr<A> ptr_;
    };

    What is nice about this approach is:
    - The responsibility of managing the A-object is moved to ptr_
    - This frees you from having to define copy operations and a
    destructor for D

    I'd even say that this corresponds to important "modern C++ design
    principles":
    - Make a class "manage" at most one resource
    ("manage" in the sense of providing custom copy ops and a dtor)
    - Avoid having to write custom copy operations and dtors for many
    of your classes.

    In addition, I suggest to exploit covariant return types w.r.t. the
    virtual clone member function.

    Cheers!
    SG
    SG, Sep 28, 2011
    #7
  8. On 9/28/11 4:39 AM, Juha Nieminen wrote:
    > Goran<> wrote:
    >> You are of course absolutely not allowed to use memcpy to copy non-POD
    >> types. I hope you understand why.

    >
    > Suppose that rather than copy the objects you want to *move* them from
    > one memory location to another, without invoking any constructors or
    > destructors. A practical example where you may want to do this is in the
    > implementation of std::vector (when the memory block allocated by it is
    > reallocated): In this case you simply want to move the raw data from one
    > place to another. You could use memcpy for this.
    >
    > However, is this a valid technique? Are there any hidden traps in doing
    > this?


    Memcpy will sometimes NOT do what you want, especially if the object
    doesn't have a trivial copy/move constructor. (It works if they are, as
    that is sort of the definition of it). The big issue is that the object
    may have pointers to pieces of itself, either explicitly in the user
    code, or implicitly in, for example, a case of virtual inheritance. The
    standard defines when it is safe to do, and when it isn't. For example a
    POD is safe to copy this way.
    Richard Damon, Sep 28, 2011
    #8
  9. Vinesh S

    Goran Guest

    On Sep 28, 10:39 am, Juha Nieminen <> wrote:
    > Goran <> wrote:
    > > You are of course absolutely not allowed to use memcpy to copy non-POD
    > > types. I hope you understand why.

    >
    >   Suppose that rather than copy the objects you want to *move* them from
    > one memory location to another, without invoking any constructors or
    > destructors. A practical example where you may want to do this is in the
    > implementation of std::vector (when the memory block allocated by it is
    > reallocated): In this case you simply want to move the raw data from one
    > place to another. You could use memcpy for this.
    >
    >   However, is this a valid technique? Are there any hidden traps in doing
    > this?


    Not that this is effectively a move, but such that after it, original
    must disappear off the face of the Earth (due to double-destruction
    otherwise). In you vector case, that could work for a wider
    range of cases, but elsewhere, where original stays visible, that's
    begging for trouble.

    Otherwise, this doesn't work in general case anyhow. Imagine merely
    that inside your object you hold a pointer to another part of same
    object, or another object, that's been "moved". (And I am positive
    that good people here will come up with more examples).

    Goran.
    Goran, Sep 28, 2011
    #9
  10. Vinesh S

    Goran Guest

    On Sep 28, 10:26 am, Vinesh S <> wrote:
    > On Sep 28, 2:08 am, Goran <> wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > On Sep 27, 9:28 pm, Vinesh S <> wrote:

    >
    > > > Hello All,

    >
    > > > i have a question with copy construction here.

    >
    > > > i have for example

    >
    > > > class A // abstract base class
    > > > {
    > > > ...

    >
    > > > }

    >
    > > > class B : public A
    > > > {
    > > > ...

    >
    > > > }

    >
    > > > class C : public A
    > > > {
    > > > ...

    >
    > > > }

    >
    > > > also i have totally an unrelated class called  D.

    >
    > > > class D
    > > > {
    > > >   D(A* basepointer , int k, int y)  // constructor
    > > >  {
    > > >     ....
    > > >      basePtr = basePointer;
    > > >  }

    >
    > > > private
    > > >     A* basePtr

    >
    > > > }

    >
    > > > QUESTION:
    > > > how do i write a copy constructor for Class D?

    >
    > > > 1. problem i face is  : if am not allowed to use memcpy ...
    > > > ... i need to copy the value pointed  by the basePtr in the copy
    > > > constructor to the resulting class.
    > > >     but i dont know what instance it holds ( whether class b or class
    > > > c ) to allocate memory and copy it

    >
    > > You are of course absolutely not allowed to use memcpy to copy non-POD
    > > types. I hope you understand why.

    >
    > > Since you are mentioning memcpy, for your copy of D, I guess you want
    > > a copy of basePtr. If so, you will need to clone it, e.g. like Paavo
    > > said. If not, you might take a look at shared_ptr class, which allows
    > > you to... well, "share" an object on the heap in various places.

    >
    > > BTW, guys, it's the second cloning question in a couple of days here.

    >
    > > Goran.

    >
    > Thanks a lot for taking time to post your answers guys,
    >
    > Goran,
    >
    > The reason am not supposed to use memcpy is ... it would just copy the
    > size of the basepointer but memory region associated to derived
    > classes wouldnt be copied ... rite ???


    No, it's fundamental, really. C++ allows you to define copy
    constructor and assignment operator for your class. As soon as you
    have that (and note: you don't have to write this yourself, compiler
    will do it if any members of your class have copy ctor/assignment, and
    simplest of things have those, e.g. std:string), memcpy will
    effectively crash your code. Most likely you'll see a crash later, not
    on the spot where you call memcpy, but still. This is simply because
    memcpy just moves bits around, it doesn't know what these bits mean
    and how are they used in your code. Only copy ctor and assignment
    operator know that, and you have to use __them__. See about rule of
    three, perhaps here: http://drdobbs.com/184401400

    Goran.
    Goran, Sep 28, 2011
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VisionSet
    Replies:
    8
    Views:
    4,872
    Tris Orendorff
    Apr 29, 2004
  2. Aire
    Replies:
    3
    Views:
    453
    Mike Wahler
    Jan 25, 2004
  3. ali
    Replies:
    4
    Views:
    558
    David Harmon
    Mar 5, 2007
  4. Generic Usenet Account
    Replies:
    10
    Views:
    2,191
  5. cinsk
    Replies:
    35
    Views:
    2,552
    James Kanze
    Oct 11, 2010
Loading...

Share This Page