Copy constructor question.

V

Vinesh S

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
 
V

Victor Bazarov

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
 
G

Goran

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.
 
V

Vinesh S

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
 
J

Juha Nieminen

Goran said:
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?
 
O

Oliver Jackson

  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.
 
S

SG

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
 
R

Richard Damon

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.
 
G

Goran

  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.
 
G

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top