Re: Virtual constructor?
Gene Bushuyev wrote:
The problem with using CRTP is that it introduces ambiguity due to multiple
inheritance, rather than overriding the virtual clone() function. Here is an
example,
template <class C>
class cloneable
{
public:
virtual C* clone() const { return new C(*this); }
};
class A : public cloneable<A> { public: A(const A&); A();};
class B : public A, public cloneable<B>
{ public: B(const B&); B();};
int main()
{
B* b = new B;
B* c = b->clone();
}
compiler cannot resolve the ambiguity between cloneable<A>::clone() and
cloneable<B>::clone().
--
Gene Bushuyev (www.gbresearch.com)
----------------------------------------------------------------
To see what is in front of one's nose needs a constant struggle ~ George Orwell
I don't know if this would work, and somehow I got different error
messages
from compiler to compiler.
template <class T>
class cloner{
protected:
T* clone() const{ return new T(*static_cast<T const*>(this)); }
cloner(){}
};
struct null_type{};
template <class T, class Parent = null_type>
struct cloneable: public Parent, private cloner<T>{
virtual T* clone() const{ return cloner<T>::clone(); }
// ^^^ note here
};
class Base: public cloneable<Base>{};
class Derived: public cloneable<Derived, Base>{};
==
Comeau C/C++ 4.3.3:
error: return type is not identical to nor covariant
with return type "Base *" of overridden virtual function
If I change T* to Parent*, it compiles.
==
GCC 3.4.5:
error: invalid covariant return type for `T* cloneable<T,
Parent>::clone() const [with T = Derived, Parent = Base]'
error: `cloner<Base>' is an inaccessible base of `Base'
If I change private inheritance to protected inheritance, plus
changing T* to Parent*, it compiles.
==
VC++ 7.1:
error C2555: 'cloneable<T,Parent>::clone': overriding virtual
function return type differs and is not covariant from
'cloneable<T>::clone'
If I change T* to Parent*, it yells another error:
error C2244: 'cloneable<T,Parent>::clone' : unable to match function
definition to an existing declaration
The only way to compile under VC++ 7.1 is change T* to null_type* or
void*, etc.
==
Could anyone elaborate for me?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]