473,396 Members | 2,158 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

forward declaration of inherited classes possible?

Hi!

The following snippet
class B;

class A
{
public:
virtual B * getB();
};

class B
{
public:
virtual A * getA();
};
defines 2 classes. Both return pointer to each other. class A compiles
only, because B is forward declared (by class B;)

Now I would like to derive from them:
class DA : public A
{
public:
// virtual DB * getB(); <- does not compile
};

class DB : public B
{
public:
virtual DA * getA();
};
Unfortunately I can not get the getB() compiled. A simple forward
declaration (class DB;) gives a:

gcc main.cpp -o test
main.cpp:20: error: invalid covariant return type for `virtual DB* DA::getB()'
main.cpp:6: error: overriding `virtual B* A::getB()'

Question: Is there a forward declaration, which shows the compiler the
inheritance as well; something like a

class DB : public B;

(which does not work)?

--

Heiner
h.********@nospam.gmx.de
Remove the nospam to get my real address
Oct 4 '05 #1
8 9598
On Tue, 04 Oct 2005 21:37:57 +0200, Heiner <no*****@t-online.de>
wrote:
Hi!

The following snippet
class B;

class A
{
public:
virtual B * getB();
};

class B
{
public:
virtual A * getA();
};
defines 2 classes. Both return pointer to each other. class A compiles
only, because B is forward declared (by class B;)

Now I would like to derive from them:
class DA : public A
{
public:
// virtual DB * getB(); <- does not compile
};

Class DA knows nothing about class B, much less about DB! DB could
inherit from anything ... but covariant return implies/requires that
the class declaring the function inherit from the original type being
returned, AFAIK [I couldn't find the appropriate passage in the
standard regarding covariant return types ... someone else able to
help here??]
class DB : public B
{
public:
virtual DA * getA();
};

Same here: class DB knows nothing about class A, nor about DA!
Unfortunately I can not get the getB() compiled. A simple forward
declaration (class DB;) gives a:

gcc main.cpp -o test
main.cpp:20: error: invalid covariant return type for `virtual DB* DA::getB()'
main.cpp:6: error: overriding `virtual B* A::getB()'

Question: Is there a forward declaration, which shows the compiler the
inheritance as well; something like a

class DB : public B;

(which does not work)?


There is no inheritance to show, hence no forward declaration.

--
Bob Hairgrove
No**********@Home.com
Oct 4 '05 #2
Heiner wrote:
The following snippet
class B;

class A
{
public:
virtual B * getB();
};

class B
{
public:
virtual A * getA();
};
defines 2 classes. Both return pointer to each other. class A compiles
only, because B is forward declared (by class B;)

Now I would like to derive from them:
class DA : public A
{
public:
// virtual DB * getB(); <- does not compile
};

class DB : public B
{
public:
virtual DA * getA();
};
Unfortunately I can not get the getB() compiled. A simple forward
declaration (class DB;) gives a:

gcc main.cpp -o test
main.cpp:20: error: invalid covariant return type for `virtual DB* DA::getB()'
main.cpp:6: error: overriding `virtual B* A::getB()'

Question: Is there a forward declaration, which shows the compiler the
inheritance as well; something like a

class DB : public B;

(which does not work)?


No. You're stuck with declaring 'getB' as returning a B*.

Or you could declare 'getDB', of course, and implement 'getB' which will
just call 'getDB'.

V
Oct 4 '05 #3
Thanks for the response.

On Tue, 04 Oct 2005 23:12:54 +0200, Bob Hairgrove wrote:
Class DA knows nothing about class B, much less about DB! DB could
inherit from anything ... but covariant return implies/requires that
the class declaring the function inherit from the original type being
returned, AFAIK [I couldn't find the appropriate passage in the
That is exactly my problem: I want to tell the compiler, that DB will
inherit from B!
Same here: class DB knows nothing about class A, nor about DA!


That's wrong. As the definition of A and DA was placed above the
definition of DB, DB knows all it needs. DB compiles without an error!

Did I make my problem more clear now?

--

Heiner
h.********@nospam.gmx.de
Remove the nospam to get my real address
Oct 4 '05 #4
Bob Hairgrove wrote:
On Tue, 04 Oct 2005 21:37:57 +0200, Heiner <no*****@t-online.de>
wrote:

Hi!

The following snippet
class B;

class A
{
public:
virtual B * getB();
};

class B
{
public:
virtual A * getA();
};
defines 2 classes. Both return pointer to each other. class A compiles
only, because B is forward declared (by class B;)

Now I would like to derive from them:
class DA : public A
{
public:
// virtual DB * getB(); <- does not compile
};
Class DA knows nothing about class B, much less about DB!


What do you mean? It knows everything about B. The definition of 'B'
is just above. It doesn't know about DB, but that's the essence of the
OP's question.
DB could
inherit from anything ... but covariant return implies/requires that
the class declaring the function inherit from the original type being
returned, AFAIK [I couldn't find the appropriate passage in the
standard regarding covariant return types ... someone else able to
help here??]


Yes, that's what the OP is trying to do.
class DB : public B
{
public:
virtual DA * getA();
};

Same here: class DB knows nothing about class A, nor about DA!


What are you talking about? It knows everything about them, the are all
declared/defined right above.
Unfortunately I can not get the getB() compiled. A simple forward
declaration (class DB;) gives a:

gcc main.cpp -o test
main.cpp:20: error: invalid covariant return type for `virtual DB* DA::getB()'
main.cpp:6: error: overriding `virtual B* A::getB()'

Question: Is there a forward declaration, which shows the compiler the
inheritance as well; something like a

class DB : public B;

(which does not work)?

There is no inheritance to show, hence no forward declaration.


It think you're way off base here.

V
Oct 4 '05 #5
On Tue, 04 Oct 2005 17:19:44 -0400, Victor Bazarov wrote:
No. You're stuck with declaring 'getB' as returning a B*.

Or you could declare 'getDB', of course, and implement 'getB' which will
just call 'getDB'.


The first will result in several casts in the user code. If A is the
source of large class tree, the second will end up in getDDB, getDDDB, ...

Both are not very elegant, but if there is no better solution I will
probably choose the latter.

Thanks for your reply

Heiner
h.********@nospam.gmx.de
Remove the nospam to get my real address
Oct 4 '05 #6
Heiner wrote:
Hi!

The following snippet
class B;

class A
{
public:
virtual B * getB();
};

class B
{
public:
virtual A * getA();
};
defines 2 classes. Both return pointer to each other. class A compiles
only, because B is forward declared (by class B;)

Now I would like to derive from them:
class DA : public A
{
public:
// virtual DB * getB(); <- does not compile
};

class DB : public B
{
public:
virtual DA * getA();
};
Unfortunately I can not get the getB() compiled. A simple forward
declaration (class DB;) gives a:

gcc main.cpp -o test
main.cpp:20: error: invalid covariant return type for `virtual DB* DA::getB()'
main.cpp:6: error: overriding `virtual B* A::getB()'

Question: Is there a forward declaration, which shows the compiler the
inheritance as well; something like a

class DB : public B;

(which does not work)?


No. The compiler must know that that DB inherits from B in order for
DA::getB()'s return type to be a legal covariant return type. And only
DB's full declaration can show that DB derives from B.

Of course it is possible to declare the return type of DA::getB as B*
and have its implementation actually return a DB*. In most cases
returning the more abstract type is the better approach since fewer
dependencies are created. After all, why does the client have to know
that DA::getB returns a pointer to a DB instead of a B? One of the
benefits of polymorphism is that the client should not care about the
exact type of an object, as long as it conforms to a particular
interface. And if knowledge of the exact type is important to a client,
why doesn't the DA provide a getDB method instead of overriding
A::getB?

Greg

Oct 5 '05 #7
Hi!

On Wed, 05 Oct 2005 01:20:33 -0700, Greg wrote:
dependencies are created. After all, why does the client have to know
that DA::getB returns a pointer to a DB instead of a B? One of the
Just convenience. If I have a DB instance, I know, that getA will return
an DA. I do not have to cast or dyncast.
benefits of polymorphism is that the client should not care about the
exact type of an object, as long as it conforms to a particular
That would be the overridden getA as well!
interface. And if knowledge of the exact type is important to a client,
why doesn't the DA provide a getDB method instead of overriding A::getB?


Today I realized, that visual C does not allow any overriding of the
getA/getB. So I decided to do exactly this (although it doubles the number
of getters of this kind).

Thanks

--

Heiner
h.********@nospam.gmx.de
Remove the nospam to get my real address
Oct 5 '05 #8

Heiner wrote:
Hi!

On Wed, 05 Oct 2005 01:20:33 -0700, Greg wrote:
dependencies are created. After all, why does the client have to know
that DA::getB returns a pointer to a DB instead of a B? One of the


Just convenience. If I have a DB instance, I know, that getA will return
an DA. I do not have to cast or dyncast.


Yes, but the client really isn't supposed to know that getA is really
returning a DA in some classes - much less be relying on it. Doing so
creates a dependency and weakens abstraction. The aim of polymorhpism
is to separate the interface from the details of its implementation,
and that can't be done if the client code is relying on the fact that
certain abstract instances have the type of certain concrete classes.
benefits of polymorphism is that the client should not care about the
exact type of an object, as long as it conforms to a particular


That would be the overridden getA as well!


Yes, but it will fix the compiler error. It's the DB* return type
(because it is different than the return type declared in the base
function), not overriding GetA itself that causes the error. Just make
sure that the implementation of GetA is in a source file and is not
inline, so that can know the actual return type.
interface. And if knowledge of the exact type is important to a client,
why doesn't the DA provide a getDB method instead of overriding A::getB?


Today I realized, that visual C does not allow any overriding of the
getA/getB. So I decided to do exactly this (although it doubles the number
of getters of this kind).

Thanks

--

Heiner
h.********@nospam.gmx.de
Remove the nospam to get my real address


Oct 6 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Simon Elliott | last post by:
For some time I've been using typedefs for STL containers for reasons outlined in: http://www.gotw.ca/gotw/046.htm However a major downside to this is that you can't forward declare a typedef...
2
by: Plok Plokowitsch | last post by:
After over a decade of programming in C++ I seem to have missed some substantial point (mental note: am I getting too old for this?). A little bit of help would be *very* appreciated. I'm trying...
2
by: blueblueblue2005 | last post by:
Hi, there was a post several days ago about using forward class declaration to solve the circular including issue, today, one question suddenly came into mind: which class should the forward class...
4
by: Ray Dukes | last post by:
What I am looking to do is map the implementation of interface properties and functions to an inherited method of the base class. Please see below. ...
23
by: mark.moore | last post by:
I know this has been asked before, but I just can't find the answer in the sea of hits... How do you forward declare a class that is *not* paramaterized, but is based on a template class? ...
1
by: toton | last post by:
Hi, I have two namespace contains class InkFrame and PrefDialog respectively. PrefDialog needs InkFrame to show the dialog over the frame. It also stores a pointer to InkFrame inside it. Now I...
6
by: Hunk | last post by:
Hi I have a question on usage of forward declarations of templates. While searching through this group , people suggested using forward declarations and typedefs for templates as // in...
4
by: Steve | last post by:
Hi, I always though to return an instance of a class by value, it had to be defined - i.e. forward declaration isn't good enough? Consider the following code snippet: class RGBA; class...
8
boxfish
by: boxfish | last post by:
Hi everyone, I'm working on a 3d maze game, and I just messed up the classes so it won't compile, and I need help sorting it out. There's a class Maze, whose members are, among other things, a list...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.