Khandelwal, Amit wrote:
I read the discussion and tried it using gcc version 3.2.3 I am getting the following error.
clone2.cpp:34: sorry, not implemented: adjusting pointers for covariant returns clone2.cpp:34: sorry, not implemented: adjusting pointers for covariant returns clone2.cpp:34: sorry, not implemented: adjusting pointers for covariant returns clone2.cpp: In member function `std::auto_ptr<Derived> Cloneable<Derived>::clone() const [with Derived = A]': clone2.cpp:50: instantiated from here
clone2.cpp:17: invalid static_cast from type `CloneableBase*' to type `A*
I think my code is right. Any thoughts?
#include <memory>
class CloneableBase { public: virtual ~CloneableBase() {};
protected: virtual CloneableBase* doClone() const = 0 ; };
template < typename Derived > class Cloneable : public virtual CloneableBase { public: typedef std::auto_ptr<Derived> AutoPtr; AutoPtr clone() const { return AutoPtr( static_cast
( doClone() ) ); } }; template < typename Derived > class NaturallyCloneable : public virtual CloneableBase { protected:
virtual CloneableBase* doClone() const { return new Derived( static_cast< const Derived& >(*this) ); } };
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(); } }
This problem was discussed in the thread and lead to the final implementation that uses dynamic_cast instead of static_cast inside of Cloneable. The final solution also provides a nice SmartPointer policy, which solves the problem of the return type (Note that the pointer policy does even support naked pointers as well). Greetings from Bremen, Daniel