I wouldn't recommend to do it that way at all.. Let Clonable be what it is, an interface with no implementation, skip the template member completely. In your example you don't need to cast anything, if you use covariant return type for overrides of clone inimplementations of Clonable:
class X : public Cloneable
{
virtual X* clone() const { return new X(data); }
};
class Y : public X
{
virtual Y* clone() const { return new Y(dataf, data); }
};
int main(int argc, char* argv[])
{
X* x = new X(1);
X* x1 = x->clone();
Y\* y = new Y(2.12, 4);
Y\* y1 = y->clone();
return 0;
}
As suggested above, usage of an std::auto_ptr is preferable, but only in client code, since otherwise you loose the ability to define covariant return types. I am using a "Cloner" utility for comfortable casts to derived types which looks something like this:
class ClonerUtility {
template <class TCoVariantClonable>
static std::auto_ptr<TCoVariantClonable> CloneAs(const Clonable& pToBeCloned) {
std::auto_ptr<Clonable> tClone(pToBeCloned.clone());
if (TCoVariantClonable* tCoVariantClone =
dynamic_cast<TCoVariantClonable*>(tClone.get())) {
tClone.reset(0);
return std::auto_ptr<TCoVariantClonable>(tCoVariantClone);
}
return std::auto_ptr<TCoVariantClonable>();
}
template<class TCoVariantClonable>
static std::auto_ptr<TCoVariantClonable> Clone(const TCoVariantClonable& pToBeCloned) {
return std::auto_ptr<TCoVariantClonable>(pToBeCloned.clone());
}
};
//
int main(int argc, char* argv[])
{
std::auto_ptr<X> tX(new X);
std::auto_ptr<X> tCloneX = ClonerUtility::Clone(*tX);
Clonable& tPureClonable = *tCloneX;
std::auto_ptr<X> tOtherCloneOfX = ClonerUtility::CloneAs<X>(tPureClonable);
}
modified on Sunday, November 7, 2010 4:05 AM