473,799 Members | 2,972 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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.********@nosp am.gmx.de
Remove the nospam to get my real address
Oct 4 '05 #1
8 9659
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!
Unfortunatel y 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**********@Ho me.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.********@nosp am.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.
Unfortunate ly 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.********@nosp am.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.********@nosp am.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.********@nosp am.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
10373
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 of a STL container: #include <vector> struct foo
2
4523
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 to gather various different classes into a common namespace using typedefs: class QWidget {}; class MyListview {}; namespace gui
2
4769
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 declaration statement be in? suppose I have a class A and B, sample code as following: // A.h #ifndef A_H #define A_H
4
2861
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. '**************************************************************************** ' Issues '****************************************************************************
23
3869
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? Here's what I thought should work, but apparently doesn't: class Foo; void f1(Foo* p)
1
5419
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 want InkFrame to be forward declared in the PrefDialog header file rather than to be included. I want to include it in the cpp file instead. There is no harm including it in PrefDialog header, and it works. But I want to save some compilation time....
6
8621
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 myfile.h template<typename T,typename R> class some_class;
4
5376
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 Colour
8
3731
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 of the walls, the user who is an object of class MazePerson, and a yellow square who is an object of class MazeMonster. MazePerson and MazeMonster are both inherited from class MazeThing, which takes care of stuff like collisions. MazePerson,...
0
9688
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9546
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10491
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10268
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9079
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7571
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5593
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4146
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3762
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.