Sign in to follow this  
TGE

COVARIANT RETURN TYPE

Recommended Posts

TGE    107
Hy everyone !

Here is a peace of code that leads to the following error when compiling : [b]invalid covariant return type for ‘virtual List* Elem::list()’[/b]

[source]class AbstractList;

class AbstractElem
{
public :
virtual AbstractList* list() = 0;
protected :
AbstractElem() {};
};

class List;

class Elem : public AbstractElem
{
public :
Elem() :
AbstractElem()
{};
virtual List* list()
{
return _list;
}
protected :
List* _list;
};

class AbstractList
{
public :
virtual AbstractElem* elem() = 0;
protected :
AbstractList() {};
};

class List : public AbstractList
{
public :
List() :
AbstractList()
{}

virtual Elem* elem()
{
return _e;
}
protected :
Elem* _e;
};

int main()
{
return 0;
}[/source]

The thing that I don't understand is why I only get this error for the [b]list()[/b] function but not for the [b]elem()[/b] function !

Could anyone explain me the difference ?

Thanks.

Share this post


Link to post
Share on other sites
Rattrap    3385
It is complaining that you changed the return type of a virtual function to a type that is incompatible with the base classes's return type. You either have to return the exact same type, or a class that is derived from that type.

In this case you are changing from a return type of AbstractList* to List*. This should be fine, except that since you are using a pre-declaration, it looks like it doesn't know that List* is derived from anything until much later in your code. You may need to break the classes out into separate headers or try moving the AbstractList and List definition before Elem's definition.

Share this post


Link to post
Share on other sites
TGE    107
Thanks for the answer ! I already tried this, separating into Elem.h and List.h and here is what I get as an error :

[b]In file included from List.h:4,
from covariant.cpp:1:
Elem.h:9: error: ISO C++ forbids declaration of ‘AbstractList’ with no type
Elem.h:9: error: ‘AbstractList’ declared as a ‘virtual’ field
Elem.h:9: error: expected ‘;’ before ‘*’ token
Elem.h:22: error: ISO C++ forbids declaration of ‘List’ with no type
Elem.h:22: error: ‘List’ declared as a ‘virtual’ field
Elem.h:22: error: expected ‘;’ before ‘*’ token
Elem.h:27: error: expected `;' before ‘protected’
Elem.h:28: error: ISO C++ forbids declaration of ‘List’ with no type
Elem.h:28: error: expected ‘;’ before ‘*’ token[/b]

Using [b]class Elem[/b]; and [b]class List;[/b] instead of #include in the header file leads to the same error than before...

Any idea ?

[source lang="cpp"]#ifndef _ELEM_
#define _ELEM_

#include "List.h"

class AbstractElem
{
public :
virtual AbstractList* list() = 0;

protected :
AbstractElem() {};
};

class Elem : public AbstractElem
{
public :
Elem() :
AbstractElem()
{};

virtual List* list()
{
return _list;
}

protected :
List* _list;
};

#endif[/source]

[source lang="cpp" ]#ifndef _LIST_
#define _LIST_

#include "Elem.h"

class AbstractList
{
public :
virtual AbstractElem* elem() = 0;

protected :
AbstractList() {};
};

class List : public AbstractList
{
public :
List() :
AbstractList()
{}

virtual Elem* elem()
{
return _e;
}

protected :
Elem* _e;
};


#endif[/source]

Share this post


Link to post
Share on other sites
rip-off    10979
Why are you using an inheritance hierarchy for containers in C++? Its totally unnecessary and underperformant, and there are superior options such as the standard C++ containers (in design as well as implementation).

Share this post


Link to post
Share on other sites
TGE    107
That was just an example. I'm not trying to develop a new container, the names are arbitrary, I just though it would be easier than using A, B or C as a class name ;)
I've got this error in a much more complex example and tried to find a more simple one.

I just want to understand why I had a compilation error in re-implemented list() but not for elem() !

Share this post


Link to post
Share on other sites
Rattrap    3385
What you are facing now are [url="http://en.wikipedia.org/wiki/Circular_dependency"]circular dependencies[/url].

About the only way I can see you solving it would be to replace the Elem* 's in List with AbstractElem* 's in the List definition and List* 's with AbstractList* 's in Elem's definition.

That being said, I would look at what rip-off said. You might give some more details on what you are trying to accomplish.

Share this post


Link to post
Share on other sites
Rattrap    3385
[quote name='TGE' timestamp='1307117053' post='4819109']
I just want to understand why I had a compilation error in re-implemented list() but not for elem() !
[/quote]

Ultimately the answer is that the pre-declaration of List didn't establish it as derived class of AbstractList only that there was a class named List ; but by the time you defined elem(), you had completely defined Elem as a dervied class of AbstractElem.

Share this post


Link to post
Share on other sites
TGE    107
[quote name='Rattrap' timestamp='1307117075' post='4819110']
About the only way I can see you solving it would be to replace the Elem* 's in List with AbstractElem* 's in the List definition and List* 's with AbstractList* 's in Elem's definition.
[/quote]

I think I'm gonna try this way. Thanks !

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this