Derek wrote:
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