Connecting Tech Pros Worldwide Forums | Help | Site Map

Duplicating objects with a common base class

Pete Nudd
Guest
 
Posts: n/a
#1: Jul 22 '05
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

John Harrison
Guest
 
Posts: n/a
#2: Jul 22 '05

re: Duplicating objects with a common base class



"Pete Nudd" <peter.nudd@nospampleasebaesystems.com> wrote in message
news:407ED970.28F2B26@nospampleasebaesystems.com.. .[color=blue]
> 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[/color]

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.


Derek
Guest
 
Posts: n/a
#3: Jul 22 '05

re: Duplicating objects with a common base class


Pete Nudd wrote:[color=blue]
> 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?[/color]

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();
Denis Remezov
Guest
 
Posts: n/a
#4: Jul 22 '05

re: Duplicating objects with a common base class


Derek wrote:[color=blue]
>
> Pete Nudd wrote:[/color]
[snip][color=blue]
>
> 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();[/color]

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
Closed Thread