Re: C++ language: Cloneable classes
My final approach:
[code]
/** Cloneable interface for classes.
* @author Krzysztof Czainski
* @created 2008.05.04
*/
#pragma once
#include <memory>
#include <boost/assert.hpp>
#include <boost/cast.hpp>
/////////////////////////////////////////////////////////////////////////////
/** Inherit virtually. Base class for Cloneable<> and
NaturallyCloneable<> */
class CloneableBase
{
public:
/** @safety AC- */
virtual ~CloneableBase() {};
protected:
/** @returns new copy of *this
* @safety aCI */
virtual CloneableBase* doClone() const = 0 ;
};
/////////////////////////////////////////////////////////////////////////////
/** class User : public Cloneable<User> */
template < typename Derived >
class Cloneable : public virtual CloneableBase
{
public:
typedef std::auto_ptr<Derived> AutoPtr;
/** @safety aCI */
AutoPtr clone() const
{
return
AutoPtr( boost::polymorphic_downcast<Derived*>( doClone() ) );
}
};
/////////////////////////////////////////////////////////////////////////////
/** class UserFinal : public NaturallyCloneable<UserFinal> */
template < typename Derived >
class NaturallyCloneable : public virtual CloneableBase
{
protected:
/** @override CloneableBase
* @safety aCI */
virtual CloneableBase* doClone() const
{
// prevent slicing and assert corectnes of static_cast
BOOST_ASSERT( typeid(*this) == typeid(Derived) );
return new Derived( static_cast< const Derived& >(*this) );
}
};
[/code]
I won't use the improved version of Daniel Kr?gler's code, because in
the example below class NaturallyCloneable<B> wouldn't provide
implementation for Cloneable<A>::doClone, which would make it
abstract.
Example:
[code]
class A : public Cloneable<A> {}; // abstract base for B and C
class B : public A, public NaturallyCloneable<B> {};
class C : public A { virtual A* doClone() const { /* return hand-made
copy of *this */ } };
[/code]
As for Dizzy's suggestion of using boost::variant, and compile-time
polymorphism: It seems like a very interesting design, which I would
have never thought about. However, I won't use it, because my design
takes advantage of runtime polymorphism any way.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]