Re: Virtual constructor?
Wu Yongwei wrote:
kanze wrote:
template< typename Derived, typename Base >
class Clonable : public Base
{
public:
Derived* clone() const
{
return new Derived(
*dynamic_cast< Derived const* >( this ) ) ;
}
private:
virtual Base* doClone() const
{
return clone() ;
}
} ;
template< typename Base >
class AbstractClonable
{
public:
AbstractClonable* clone() const
{
Base* result = doClone() ;
assert( typeid( result ) == typeid( *this ) ) ;
return result ;
}
private:
virtual Base* doClone() const = 0 ;
} ;
I actually find your code quite useful. However, I do find an
issue, when the class hierarchy is as follows:
class A : public public AbstractClonable<A> {};
class B : public Clonable<B, A> {};
class C : public Clonable<C, A> {}'
B* p = new C();
Then p->clone() will really return a B object instead of C.
Good point.
I guess in this case, you need to put the actual implementation
in the virtual function, and have the non-virtual call the
virtual in the derived classes. (The basic idiom is from Barton
and Nackman -- the goal was different, and the context as well.)
The solutions I find so far are:
1) Declare only leaf-node objects can be instantiated and let B inherit
from A instead of Clonable<B, A>;
2) Change Clonable::clone() to this effect:
Derived* clone() const
{
if (typeid(Derived) == typeid(*this))
return new Derived(*static_cast<const Derived*>(this));
else
return static_cast<Derived*>(doClone());
}
Any comments?
What's wrong with just:
Derived* clone() const
{
Derived* result = doClone() ;
assert( typeid( *result ) == typeid( *this ) ) ;
return result ;
}
// ...
Derived* doClone() const
{
return new Derived( *dynamic_cast< Derived const* >( this ) ) ;
}
Any better solutions? Anyone knows about the overhead of
typeid?
Fairly high, I believe. But then, so is the overhead of dynamic
allocation and in many cases, of the copy constructor.
--
James Kanze kanze.james@neuf.fr
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]