Re: problems with polymorphism and inheritance with templates
On 29 Aug., 17:47, Frank Buss wrote:
This code:
template<class T>
class Foo
{
public:
T* member;
};
Ok, let's assume Foo<T> has a default constructor that initializes
'member' with a null pointer.
class Base
{
};
typedef Foo<Base> BaseFoo;
class Derived
{
};
It seems, you forgot to add Base as a base class for Derived here.
typedef Foo<Derived> DerivedFoo;
int main(int argc, char** argv)
{
DerivedFoo* dfoo = new DerivedFoo();
BaseFoo* bfoo = dfoo;
return 0;
}
Why do you 'new' DerivedFoo here?
doesn't compile, the compiler says "cannot convert ?DerivedFoo*? to
?BaseFoo*? in initialization".
DerivedFoo and BaseFoo are two distinct types that have no inheritence
relationship. But you can make a DerivedFoo convertible to a BaseFoo
and this is probably what you really wanted to do:
int main(int argc, char** argv)
{
DerivedFoo dfoo;
BaseFoo bfoo = dfoo;
return 0;
}
You can do this by providing a templated conversion constructor in the
Foo class template:
template<class T>
class Foo
{
public:
T* member;
Foo() : member(0) {} // default ctor
template<class U>
Foo(Foo<U> const& f) : member(f.member) {}
};
As a bonus you might want to disable this templated conversion
constructor in case U* is not convertible to T* for overloading
reasons. It's possible with a bit of meta-programming but I think this
would be too much information for now.
I know that something similiar (but not really the same) is possible,
because shared_ptr can do it, e.g. this one compiles with g++ 4.3.2:
[...]
typedef shared_ptr<Base> BasePtr;
typedef shared_ptr<Derived> DerivedPtr;
int main(int argc, char** argv)
{
DerivedPtr dptr(new Derived());
BasePtr bptr = dptr;
return 0;
}
Right. The thing is DerivedPtr is convertible to BasePtr but the types
are not reference-related because there is no inheritence relationship
between these two types. And since they are not reference-related you
cannot use a pointer of type BasePtr* to point to an object of type
DerivedPtr.
Maybe the typedefs are confusing you. You are aware of the fact that
BasePtr* is a pointer to a struct containing a pointer to Base, right?
The inheritence relationship is only between Base and Derived, not
between BasePtr and DerivedPtr. Is it possible that you missed one
level of indirection?
Cheers!
SG
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]