Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Copy constructor question.

Reply
Thread Tools

Copy constructor question.

 
 
Vinesh S
Guest
Posts: n/a
 
      09-27-2011
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
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      09-27-2011
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
 
Reply With Quote
 
 
 
 
Goran
Guest
Posts: n/a
 
      09-28-2011
On Sep 27, 9:28*pm, Vinesh S <(E-Mail Removed)> 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.
 
Reply With Quote
 
Vinesh S
Guest
Posts: n/a
 
      09-28-2011
On Sep 28, 2:08*am, Goran <(E-Mail Removed)> wrote:
> On Sep 27, 9:28*pm, Vinesh S <(E-Mail Removed)> 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
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      09-28-2011
Goran <(E-Mail Removed)> 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?
 
Reply With Quote
 
Oliver Jackson
Guest
Posts: n/a
 
      09-28-2011
On Sep 28, 1:39*am, Juha Nieminen <(E-Mail Removed)> wrote:
> Goran <(E-Mail Removed)> 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.

 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      09-28-2011
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 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 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
 
Reply With Quote
 
Richard Damon
Guest
Posts: n/a
 
      09-28-2011
On 9/28/11 4:39 AM, Juha Nieminen wrote:
> Goran<(E-Mail Removed)> 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.
 
Reply With Quote
 
Goran
Guest
Posts: n/a
 
      09-28-2011
On Sep 28, 10:39*am, Juha Nieminen <(E-Mail Removed)> wrote:
> Goran <(E-Mail Removed)> 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.
 
Reply With Quote
 
Goran
Guest
Posts: n/a
 
      09-28-2011
On Sep 28, 10:26*am, Vinesh S <(E-Mail Removed)> wrote:
> On Sep 28, 2:08*am, Goran <(E-Mail Removed)> wrote:
>
>
>
>
>
>
>
>
>
> > On Sep 27, 9:28*pm, Vinesh S <(E-Mail Removed)> 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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
template copy constructor vs normal copy constructor cinsk C++ 35 10-10-2010 11:14 PM
A constructor calling another constructor (default constructor)? Generic Usenet Account C++ 10 11-28-2007 04:12 AM
Calling base class constructor from derived class Copy constructor ali C++ 4 03-05-2007 09:15 AM
deep/shallow copy - constructor v Object.copy() VisionSet Java 8 04-29-2004 10:41 PM
Copy constructor hides default constructor Aire C++ 3 01-25-2004 05:47 PM



Advertisments