Re: covariant return type and forward declaration
On Nov 11, 11:12 pm, zade <zhaohongc...@gmail.com> wrote:
Codes like below:
struct BaseDescriptor;
struct Base
{
virtual BaseDescriptor* getDescriptor() {return NULL;}
};
struct BaseDescriptor
{
virtual Base* createValue() const {return NULL;}
};
struct DerivedDescriptor;
struct Derived : public Base
{
virtual DerivedDescriptor* getDescriptor() {return NULL;}
};
struct DerivedDescriptor : public BaseDescriptor
{
virtual Derived* createValue() const {return NULL;}
};
MSVS and GCC both give compile error message. In MSVS, it says:
error C2555: 'Covariant::Derived::getDescriptor': overriding virtual
function return type differs and is not covariant from
'Covariant::Base::getDescriptor'
It seems that covariant return type and forward declaration can't be
satsified simutaneously.
Yes. This is because in the line
virtual DerivedDescriptor* getDescriptor() {return NULL;}
the compiler does not yet know that DerivedDescriptor derives from
BaseDescriptor, because it is incomplete ('forward declared').
But how can I correct it?
You can't directly, but you can work around the problem with the Non-
Virtual Interface idiom like so:
struct BaseDescriptor;
struct Base
{
BaseDescriptor* getDescriptor() {return
getDescriptorImpl();}
private:
virtual BaseDescriptor* getDescriptorImpl() {return
NULL;}
};
struct BaseDescriptor
{
virtual Base* createValue() const {return NULL;}
};
struct DerivedDescriptor;
struct Derived : public Base
{
DerivedDescriptor* getDescriptor();
{ return static_cast<DerivedDescriptor*>
(getDescriptorImpl()); }
private:
virtual BaseDescriptor* getDescriptorImpl() {return
NULL;}
};
struct DerivedDescriptor : public BaseDescriptor
{
virtual Derived* createValue() const {return NULL;}
};
Effectively you implement by hand what the compiler would do for you.
You must be careful to ensure that Derived::getDescriptorImpl() (and
all overrides) really do return a DerivedDescriptor* (or null, as
here).
Yechezkel Mett
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]