Duplicating objects with a common base class

P

Pete Nudd

I have a system in which potentialy 100's of classes derive directly
from a common base class. I will often have a pointer of the base class
type which points to an object of a derived class. Now the hard bit: I
need to be able to create a copy of the object.

I know I could write a virtual Duplicate() function in the base class,
and then override it in each of the derived classes, but that seems very
time consuming when the code is going to look more or less identical in
each case.


Any Ideas?

TIA

Pete Nudd
 
J

John Harrison

Pete Nudd said:
I have a system in which potentialy 100's of classes derive directly
from a common base class. I will often have a pointer of the base class
type which points to an object of a derived class. Now the hard bit: I
need to be able to create a copy of the object.

I know I could write a virtual Duplicate() function in the base class,
and then override it in each of the derived classes, but that seems very
time consuming when the code is going to look more or less identical in
each case.


Any Ideas?

TIA

Pete Nudd

You're doing it the right way, there isn't a better way in C++. Some people
would cut out some of the repetition by using a macro but personally I
wouldn't recommend it. Its only a one line function so it not too hard to
write it each time.

john

BTW the traditional name for the function you are calling Duplicate is
Clone.
 
D

Derek

Pete said:
I have a system in which potentialy 100's of classes
derive directly from a common base class. I will often
have a pointer of the base class type which points to an
object of a derived class. Now the hard bit: I need to be
able to create a copy of the object.

I know I could write a virtual Duplicate() function in
the base class, and then override it in each of the
derived classes, but that seems very time consuming when
the code is going to look more or less identical in each
case.

Any Ideas?

You could use a template to supply a clone() function.
(I think -- you might want a second opinion because I'm
making this up as I go along.) Say your base is:

class Base
{
public:
virtual Base* clone() const = 0;
virtual ~Base() {}
};

Create a template that defines clone() for any type T
and is itself derived from Base:

template<class T>
class CloneableBase : public Base
{
public:
Base* clone() const
{
return new T(dynamic_cast<const T&>(*this));
}
};

Now inherit from Cloneable instead of using Base
directly:

class Foo : public CloneableBase<Foo> {};
class Bar : public CloneableBase<Bar> {};

And you can write:

Base* pb1 = new Foo;
Base* pb2 = pb1->clone();
 
D

Denis Remezov

Derek said:
Pete Nudd wrote: [snip]

You could use a template to supply a clone() function.
(I think -- you might want a second opinion because I'm
making this up as I go along.) Say your base is:

class Base
{
public:
virtual Base* clone() const = 0;
virtual ~Base() {}
};

Create a template that defines clone() for any type T
and is itself derived from Base:

template<class T>
class CloneableBase : public Base
{
public:
Base* clone() const
{
return new T(dynamic_cast<const T&>(*this));
}
};

Now inherit from Cloneable instead of using Base
directly:

class Foo : public CloneableBase<Foo> {};
class Bar : public CloneableBase<Bar> {};

And you can write:

Base* pb1 = new Foo;
Base* pb2 = pb1->clone();

Nitpicking: I'd disagree with the use of dynamic_cast here (other than
for debugging). If CloneableBase<T> is used as intended:
class Bar : public CloneableBase<Bar> {};

then the result of dynamic_cast is equivalent to static_cast.
The only time its observed behaviour will differ from that of static_cast
is when someone grossly misuses CloneableBase<T>, e.g.
class Bar : public CloneableBase<Foo> {};

This, however, should be detected at compile time and, at any rate, never
happen in the production code, so static_cast will do. If this still
didn't sound safe enough, I'd just revert to the original scheme.

(FWIW, I use dynamic_cast only when I really have to (i.e. when downcasting
can only be resolved at run-time and must be controlled for safety, and
there are no design alternatives). The former use is a domain serviced
well enough by virtual functions alone. On a practical note, at least
some popular implementations of dynamic_cast are very inefficient).

Denis
 

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,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top