Copying Polymorphically

M

Matt Bitten

I want to make a copy of an object that is passed to me
via a base class pointer. No slicing allowed, so the copy
has to be the same dynamic type as the original. How do I
do this?

base_class * clone(const base_class * orig)
{
base_class * p;

... // A miracle occurs (HOW?)

// And now p points to a copy of *orig,
// with the same dynamic type as *orig.

return p;
}

Now I want to be able to do this:

class base_class { ... };
class derived_class : public base_class { ... };

derived_class x;
base_class * newxp = clone(&x);
// Now newxp points to a copy of x.
// The copy has type derived_class.
 
D

David White

Matt Bitten said:
I want to make a copy of an object that is passed to me
via a base class pointer. No slicing allowed, so the copy
has to be the same dynamic type as the original. How do I
do this?

base_class * clone(const base_class * orig)
{
base_class * p;

... // A miracle occurs (HOW?)

// And now p points to a copy of *orig,
// with the same dynamic type as *orig.

return p;
}

Now I want to be able to do this:

class base_class { ... };
class derived_class : public base_class { ... };

derived_class x;
base_class * newxp = clone(&x);
// Now newxp points to a copy of x.
// The copy has type derived_class.

Make your clone function a virtual member and override it in each derived
class. Each clone function returns an instance of the class it belongs to.

DW
 
R

Rolf Magnus

Matt said:
I want to make a copy of an object that is passed to me
via a base class pointer. No slicing allowed, so the copy
has to be the same dynamic type as the original. How do I
do this?

base_class * clone(const base_class * orig)
{
base_class * p;

... // A miracle occurs (HOW?)

// And now p points to a copy of *orig,
// with the same dynamic type as *orig.

return p;
}

Now I want to be able to do this:

class base_class { ... };
class derived_class : public base_class { ... };

derived_class x;
base_class * newxp = clone(&x);
// Now newxp points to a copy of x.
// The copy has type derived_class.

Make clone() a pure virtual member function of base_class:

class base_class
{
public:
virtual base_class* clone() const = 0;
//...
};

And add an implementation to derived_class:

class derived_class
{
public:
virtual derived_class* clone() const
{
return new derived_class(*this);
}
//...
};
 
M

Matt Bitten

--- Rolf Magnus said:
clone() a pure virtual member function of base_class:
[etc]

Thanks!

By the way, just for curiousity's sake, is it *possible* to do
this without a virtual member function? I'm guessing it is
not.
 
C

Cy Edmunds

Matt Bitten said:
--- Rolf Magnus said:
clone() a pure virtual member function of base_class:
[etc]

Thanks!

By the way, just for curiousity's sake, is it *possible* to do
this without a virtual member function? I'm guessing it is
not.

Well, it's sort of possible, but the solution is truly horrible:

Car *pcar = dynamic_cast<Car*>(&vehicle);
if (pcar)
// copy it
else
{
Bus *pbus = dynamic_cast<Bus*>(&vehicle);
if (pbus)
// copy it
else
{
// ad nauseum

This sort of code is a sure sign of bad design.

However, be very careful with virtual clone functions. You can easily return
the wrong type if you are not careful. This is likely to cause hard to find
bugs.
 
D

David White

Matt Bitten said:
By the way, just for curiousity's sake, is it *possible* to do
this without a virtual member function? I'm guessing it is
not.

If you go to enough trouble you can do just about anything another way. The
first C++ compiler produced C code, which was then compiled by a C compiler,
so anything you can do in C++ can be done in C. Nothing could be more
suitable to achieve with virtual functions than clone functions. You could
do it another way if you were determined to, but you couldn't do it better.

DW
 

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,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top