Re: C++ language: Cloneable classes
On May 9, 5:15 pm, Daniel Kr?gler <daniel.krueg...@googlemail.com>
wrote:
I still think that it would be fine to add:
protected:
virtual Cloneable* doClone() const = 0;
In this small example main.cpp:
[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 new C; } };
int main()
{
B b;
C c;
b.clone();
c.clone();
b.clone< boost::shared_ptr<A> >(); // see code below
c.clone< boost::shared_ptr<A> >();
}
[/code]
g++ main.cpp
main.cpp:12: error: cannot declare variable ?b? to be of abstract type
?B?
main.cpp:6: note: because the following virtual functions are pure
within ?B?:
cloneable.h:63: note: Cloneable<Derived, DefaultPtrPolicy>*
Cloneable<Derived, DefaultPtrPolicy>::doClone() const [with Derived =
A, DefaultPtrPolicy = std::auto_ptr<A>]
Adding this breaks compatibility with NaturallyCloneable<> -- class B
from the exmaple main.cpp becomes abstract, and code doesn't compile.
An interesting enhancement proposal for Cloneable could be to
add one further template parameter as smart-pointer policy
Yes, this is fine. And by means of the virtual inheritance you
simulate what other languages usually call "interface" (but
you know that). And if you use Cloneable<D, boost::shared_ptr<D> >
this will match the style of those languages even more ;-)
Yes, exactly ;-)
Here's the enhancement You proposed with another little enhancement of
my own:
[code]
template < typename Derived, typename DefaultPtrPolicy =
std::auto_ptr<Derived> >
class Cloneable : public virtual CloneableBase
{
public:
BOOST_STATIC_ASSERT(( boost::is_base_of< Derived, typename
DefaultPtrPolicy::element_type >::value ));
typedef DefaultPtrPolicy SmartPtr;
SmartPtr clone() const { return clone<SmartPtr>(); }
template < typename OtherPtrPolicy >
OtherPtrPolicy clone() const
{
BOOST_STATIC_ASSERT(( boost::is_base_of< Derived, typename
OtherPtrPolicy::element_type >::value ));
// note: must be dynamic_cast due to virtual inheritance of
CloneableBase
Derived* p = dynamic_cast<Derived*>( doClone() );
BOOST_ASSERT( p != NULL );
return OtherPtrPolicy( p );
}
// note: the below would break compatibility with NaturallyCloneable
//protected:
// Cloneable* doClone() const = 0;
};
[/code]
Still, one thing bothers me.. The static assertion "is_base_of" should
stay, but it would be nice to also be able to use a normal Derived*
instead of some smart ptr type. Can that be achieved simply?
class X : public Cloneable<X,X*>, NaturallyCloneable<X> {};
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]