By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,186 Members | 1,551 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,186 IT Pros & Developers. It's quick & easy.

Overriding a virtual function and changing its return type --- dependency issues

P: n/a
Hi,

I'm experiencing an annoying issue. Here is a simplified idea of what
I am trying to do. Inclusion guards aren't shown for readability. I
hope this isn't too confusing; I don't think a description would be as
clear as an example.

-----[ParentA.h]------
class ParentA {};

-----[ChildA.h]------
#include "ParentA.h"
#include "ChildB.h"
class ChildA: public ParentA { ChildB foo; };

-----[ParentB.h]------
class ParentA;
class ParentB {
virtual ParentA& getA() = 0;
};

-----[ChildB.h]------
#include "ParentB.h"
class ChildA;
class ChildB: public ParentB {
ChildA& getA();
};

---

When I try to compile my project, MSVC 2002 gives me the following
error message:

error C2555: 'ChildB::getA': overriding virtual function return type
differs and is not covariant from 'ParentB::getA'

I took this to mean that the problem is that the compiler doesn't
realize that ChildA is a type of ParentA because I forward-declared
ChildA instead of including its header file, so ChildB::getA looks
like an invalid signature. The problem is that if I replace the
forward-declaration with "#include ChildA.h", I encounter a dependency
issue, since ChildA.h also has to include ChildB.h because the ChildA
class contains a ChildB object.

Is there a way to specify that ChildA is a child of ParentA in a
forward-declaration? If not, does anyone have any suggestions for
getting around this problem?

Thanks.

Mar 8 '06 #1
Share this Question
Share on Google+
13 Replies


P: n/a

"ctor" <blhbalh@.balh> wrote in message
news:u4********************************@4ax.com...
Hi,

I'm experiencing an annoying issue. Here is a simplified idea of what
I am trying to do. Inclusion guards aren't shown for readability. I
hope this isn't too confusing; I don't think a description would be as
clear as an example.

-----[ParentA.h]------
class ParentA {};

-----[ChildA.h]------
#include "ParentA.h"
#include "ChildB.h"
class ChildA: public ParentA { ChildB foo; };

-----[ParentB.h]------
class ParentA;
class ParentB {
virtual ParentA& getA() = 0;
};

-----[ChildB.h]------
#include "ParentB.h"
class ChildA;
class ChildB: public ParentB {
ChildA& getA();
};

---


Why not return a ParentA& from ChildB::getA(), just like you do in
ParentB::getA()? You're returning a reference, so polymorphism will come
into play, and any calls to virtual functions in the returned ParentA object
will correctly execute their ChildA counterparts. And by publicly
inheriting, you've said that ChildA "is a" ParentA, so there shouldn't be
any problem. Any reason this idea won't work?

-Howard
Mar 8 '06 #2

P: n/a
On Wed, 08 Mar 2006 19:03:17 GMT, "Howard" <al*****@hotmail.com>
wrote:

"ctor" <blhbalh@.balh> wrote in message
news:u4********************************@4ax.com.. .
Hi,

I'm experiencing an annoying issue. Here is a simplified idea of what
I am trying to do. Inclusion guards aren't shown for readability. I
hope this isn't too confusing; I don't think a description would be as
clear as an example.

-----[ParentA.h]------
class ParentA {};

-----[ChildA.h]------
#include "ParentA.h"
#include "ChildB.h"
class ChildA: public ParentA { ChildB foo; };

-----[ParentB.h]------
class ParentA;
class ParentB {
virtual ParentA& getA() = 0;
};

-----[ChildB.h]------
#include "ParentB.h"
class ChildA;
class ChildB: public ParentB {
ChildA& getA();
};

---


Why not return a ParentA& from ChildB::getA(), just like you do in
ParentB::getA()? You're returning a reference, so polymorphism will come
into play, and any calls to virtual functions in the returned ParentA object
will correctly execute their ChildA counterparts. And by publicly
inheriting, you've said that ChildA "is a" ParentA, so there shouldn't be
any problem. Any reason this idea won't work?

-Howard


Hi Howard, thanks for the response. Unfortunately that won't suit my
purposes because ChildB::getA() is a function that only gets called by
ChildB itself. ChildB knows that it should be getting a ChildA
reference, and so it expects to be able to use ChildA's extended
interface.
Mar 8 '06 #3

P: n/a

"ctor" <blhbalh@.balh> wrote in message
news:c1********************************@4ax.com...
On Wed, 08 Mar 2006 19:03:17 GMT, "Howard" <al*****@hotmail.com>
wrote:

"ctor" <blhbalh@.balh> wrote in message
news:u4********************************@4ax.com. ..
Hi,

I'm experiencing an annoying issue. Here is a simplified idea of what
I am trying to do. Inclusion guards aren't shown for readability. I
hope this isn't too confusing; I don't think a description would be as
clear as an example.

-----[ParentA.h]------
class ParentA {};

-----[ChildA.h]------
#include "ParentA.h"
#include "ChildB.h"
class ChildA: public ParentA { ChildB foo; };

-----[ParentB.h]------
class ParentA;
class ParentB {
virtual ParentA& getA() = 0;
};

-----[ChildB.h]------
#include "ParentB.h"
class ChildA;
class ChildB: public ParentB {
ChildA& getA();
};

---


Why not return a ParentA& from ChildB::getA(), just like you do in
ParentB::getA()? You're returning a reference, so polymorphism will come
into play, and any calls to virtual functions in the returned ParentA
object
will correctly execute their ChildA counterparts. And by publicly
inheriting, you've said that ChildA "is a" ParentA, so there shouldn't be
any problem. Any reason this idea won't work?

-Howard


Hi Howard, thanks for the response. Unfortunately that won't suit my
purposes because ChildB::getA() is a function that only gets called by
ChildB itself. ChildB knows that it should be getting a ChildA
reference, and so it expects to be able to use ChildA's extended
interface.


But it can! That's what polymorphism is all about. You don't show the
definition of getA(), but if it constructs (or otherwise obtains) a ChildA
object, then referring to it via a ParentA reference (or pointer) is
perfectly valid.

If you need to refer to members which exist ONLY in the ChildA object, then
you can use dynamic_cast on the returned reference where needed.

If you don't want to return a ParentA& reference from getA(), then why did
you make it a virtual function in ParentB in the first place?

-Howard


Mar 8 '06 #4

P: n/a
On Wed, 08 Mar 2006 19:23:27 GMT, "Howard" <al*****@hotmail.com>
wrote:
Hi Howard, thanks for the response. Unfortunately that won't suit my
purposes because ChildB::getA() is a function that only gets called by
ChildB itself. ChildB knows that it should be getting a ChildA
reference, and so it expects to be able to use ChildA's extended
interface.


But it can! That's what polymorphism is all about. You don't show the
definition of getA(), but if it constructs (or otherwise obtains) a ChildA
object, then referring to it via a ParentA reference (or pointer) is
perfectly valid.

If you need to refer to members which exist ONLY in the ChildA object, then
you can use dynamic_cast on the returned reference where needed.

If you don't want to return a ParentA& reference from getA(), then why did
you make it a virtual function in ParentB in the first place?

-Howard


Thanks.

I didn't want to use a dynamic_cast because getA() will be called very
frequently (several hundred times per second).

I declared "virtual ParentA& ParentB::getA()" because ParentB needs to
call this function and use the interface pf the returned ParentA
reference.

Does that make sense?
Mar 8 '06 #5

P: n/a
On 2006-03-08, ctor <blhbalh@> wrote:
Hi,

I'm experiencing an annoying issue. Here is a simplified idea of
what I am trying to do. Inclusion guards aren't shown for
readability. I hope this isn't too confusing; I don't think a
description would be as clear as an example.

-----[ParentA.h]------
class ParentA {};

-----[ChildA.h]------
#include "ParentA.h"
#include "ChildB.h"
class ChildA: public ParentA { ChildB foo; };

-----[ParentB.h]------
class ParentA;
class ParentB {
virtual ParentA& getA() = 0;
};

-----[ChildB.h]------
#include "ParentB.h"
class ChildA;
class ChildB: public ParentB {
ChildA& getA();
};

---

When I try to compile my project, MSVC 2002 gives me the following
error message:

error C2555: 'ChildB::getA': overriding virtual function return type
differs and is not covariant from 'ParentB::getA'
Interesting problem. I think you need a proxy object for the A
hierarchy. Usually, an extra layer of indirection can solve this sort
of problem.

-----[ProxyA.h]-----
class ParentA;
struct ProxyA
{
ProxyA(ParentA& aa): a(aa) { }
ParentA& a; /* You can fiddle with this interface to meet your needs. */
};

Then modify ParentB.h, and ChildB.h:

-----[ParentB.h]-----
#include "ProxyA.h"
class ParentB
{
virtual ProxyA getA() = 0;
};
-----[ChildB.h]-----
#include "ParentB.h"
class ChildB: public ParentB
{
ProxyA getA();
};
Is there a way to specify that ChildA is a child of ParentA in a
forward-declaration?


I don't believe so.

--
Neil Cerutti
Caution: Cape does not enable user to fly. --Kenner's Batman
costume
Mar 8 '06 #6

P: n/a
On 2006-03-08, Neil Cerutti <le*******@email.com> wrote:
On 2006-03-08, ctor <blhbalh@> wrote:
Interesting problem. I think you need a proxy object for the A
hierarchy. Usually, an extra layer of indirection can solve this sort
of problem.

-----[ProxyA.h]-----
class ParentA;
struct ProxyA
{
ProxyA(ParentA& aa): a(aa) { }
ParentA& a; /* You can fiddle with this interface to meet your needs. */
};
Based on one of you other replies in this thread, you actually need:

-----[ProxyA.h]-----
class ChildA;
struct ProxyA
{
ProxyA(ChildA& aa): a(aa) { }
ChildA& a;
};

No other changes necessary.
Then modify ParentB.h, and ChildB.h:

-----[ParentB.h]-----
#include "ProxyA.h"
class ParentB
{
virtual ProxyA getA() = 0;
};
-----[ChildB.h]-----
#include "ParentB.h"
class ChildB: public ParentB
{
ProxyA getA();
};

--
Neil Cerutti
Caution: Cape does not enable user to fly. --Kenner's Batman
costume
Mar 8 '06 #7

P: n/a

"ctor" <blhbalh@.balh> wrote in message
news:bv********************************@4ax.com...
On Wed, 08 Mar 2006 19:23:27 GMT, "Howard" <al*****@hotmail.com>
wrote:
Hi Howard, thanks for the response. Unfortunately that won't suit my
purposes because ChildB::getA() is a function that only gets called by
ChildB itself. ChildB knows that it should be getting a ChildA
reference, and so it expects to be able to use ChildA's extended
interface.
But it can! That's what polymorphism is all about. You don't show the
definition of getA(), but if it constructs (or otherwise obtains) a ChildA
object, then referring to it via a ParentA reference (or pointer) is
perfectly valid.

If you need to refer to members which exist ONLY in the ChildA object,
then
you can use dynamic_cast on the returned reference where needed.

If you don't want to return a ParentA& reference from getA(), then why did
you make it a virtual function in ParentB in the first place?

-Howard


Thanks.

I didn't want to use a dynamic_cast because getA() will be called very
frequently (several hundred times per second).


That's not very frequently, and I doubt the cost of several hundred
dynamic_casts would be very high. (I'm not familiar with exactly how it's
accomplished, however.) Have you profiled the use of dynamic cast, and seen
that it causes problems?

I declared "virtual ParentA& ParentB::getA()" because ParentB needs to
call this function and use the interface pf the returned ParentA
reference.

Then why is ParentB::getA() _pure_ virtual, if ParentB needs to call it?

And what's the problem using a ChildB reference as it if were a reference to
a ParentB object? Every ChildB object IS A ParentB object.
Does that make sense?


Not really. Without seeing how any of this code is used, I can't really
guess what you're trying to accomplish. (But I still think returning
Parent& from the overriding function is what you need.)

-Howard

Mar 8 '06 #8

P: n/a
On Wed, 08 Mar 2006 20:55:08 GMT, "Howard" <al*****@hotmail.com>
wrote:

"ctor" <blhbalh@.balh> wrote in message
news:bv********************************@4ax.com.. .
On Wed, 08 Mar 2006 19:23:27 GMT, "Howard" <al*****@hotmail.com>
wrote:
Hi Howard, thanks for the response. Unfortunately that won't suit my
purposes because ChildB::getA() is a function that only gets called by
ChildB itself. ChildB knows that it should be getting a ChildA
reference, and so it expects to be able to use ChildA's extended
interface.

But it can! That's what polymorphism is all about. You don't show the
definition of getA(), but if it constructs (or otherwise obtains) a ChildA
object, then referring to it via a ParentA reference (or pointer) is
perfectly valid.

If you need to refer to members which exist ONLY in the ChildA object,
then
you can use dynamic_cast on the returned reference where needed.

If you don't want to return a ParentA& reference from getA(), then why did
you make it a virtual function in ParentB in the first place?

-Howard

Thanks.

I didn't want to use a dynamic_cast because getA() will be called very
frequently (several hundred times per second).


That's not very frequently, and I doubt the cost of several hundred
dynamic_casts would be very high. (I'm not familiar with exactly how it's
accomplished, however.) Have you profiled the use of dynamic cast, and seen
that it causes problems?


If you're not familiar with it, why are you giving me a lecture?

I declared "virtual ParentA& ParentB::getA()" because ParentB needs to
call this function and use the interface pf the returned ParentA
reference.

Then why is ParentB::getA() _pure_ virtual, if ParentB needs to call it?


Obviously ParentB is an abstract class, so when I say ParentB needs to
call getA(), I'm talking about a sub-object ParentB within a ChildB
object.
And what's the problem using a ChildB reference as it if were a reference to
a ParentB object? Every ChildB object IS A ParentB object.


The ChildA class has a public function "doSomething()" that ParentA
doesn't have.

ChildB needs to call getA().doSomething();
Mar 8 '06 #9

P: n/a
On 8 Mar 2006 20:59:10 +0100, Neil Cerutti <le*******@email.com>
wrote:
On 2006-03-08, Neil Cerutti <le*******@email.com> wrote:
On 2006-03-08, ctor <blhbalh@> wrote:
Interesting problem. I think you need a proxy object for the A
hierarchy. Usually, an extra layer of indirection can solve this sort
of problem.

-----[ProxyA.h]-----
class ParentA;
struct ProxyA
{
ProxyA(ParentA& aa): a(aa) { }
ParentA& a; /* You can fiddle with this interface to meet your needs. */
};


Based on one of you other replies in this thread, you actually need:

-----[ProxyA.h]-----
class ChildA;
struct ProxyA
{
ProxyA(ChildA& aa): a(aa) { }
ChildA& a;
};

No other changes necessary.


Interesting idea, but I don't think that does what I need. Sometime
in the future, ChildB may get a sibling whose getA() function needs to
return a reference to a sibling of ChildA.

Thanks for the suggestion, though. I do have a workaround for this
that depends on the implementation specifics, but I really didn't want
to have to do it that way.
Then modify ParentB.h, and ChildB.h:

-----[ParentB.h]-----
#include "ProxyA.h"
class ParentB
{
virtual ProxyA getA() = 0;
};
-----[ChildB.h]-----
#include "ParentB.h"
class ChildB: public ParentB
{
ProxyA getA();
};


Mar 8 '06 #10

P: n/a

"ctor" <blhbalh@.balh> wrote in message
news:jh********************************@4ax.com...
On Wed, 08 Mar 2006 20:55:08 GMT, "Howard" <al*****@hotmail.com>
wrote:

"ctor" <blhbalh@.balh> wrote in message
news:bv********************************@4ax.com. ..
On Wed, 08 Mar 2006 19:23:27 GMT, "Howard" <al*****@hotmail.com>
wrote:
> Hi Howard, thanks for the response. Unfortunately that won't suit my
> purposes because ChildB::getA() is a function that only gets called by
> ChildB itself. ChildB knows that it should be getting a ChildA
> reference, and so it expects to be able to use ChildA's extended
> interface.

But it can! That's what polymorphism is all about. You don't show the
definition of getA(), but if it constructs (or otherwise obtains) a
ChildA
object, then referring to it via a ParentA reference (or pointer) is
perfectly valid.

If you need to refer to members which exist ONLY in the ChildA object,
then
you can use dynamic_cast on the returned reference where needed.

If you don't want to return a ParentA& reference from getA(), then why
did
you make it a virtual function in ParentB in the first place?

-Howard
Thanks.

I didn't want to use a dynamic_cast because getA() will be called very
frequently (several hundred times per second).
That's not very frequently, and I doubt the cost of several hundred
dynamic_casts would be very high. (I'm not familiar with exactly how it's
accomplished, however.) Have you profiled the use of dynamic cast, and
seen
that it causes problems?


If you're not familiar with it, why are you giving me a lecture?


Have you profiled the use of dynamic cast, and seen that it _actually_
causes problems for you? If not, why are you assuming it will be a
significant problem? There's a common saying here: "Premature optimization
is the root of all evil."

I declared "virtual ParentA& ParentB::getA()" because ParentB needs to
call this function and use the interface pf the returned ParentA
reference.


Then why is ParentB::getA() _pure_ virtual, if ParentB needs to call it?


Obviously ParentB is an abstract class, so when I say ParentB needs to
call getA(), I'm talking about a sub-object ParentB within a ChildB
object.
And what's the problem using a ChildB reference as it if were a reference
to
a ParentB object? Every ChildB object IS A ParentB object.


The ChildA class has a public function "doSomething()" that ParentA
doesn't have.

ChildB needs to call getA().doSomething();


So... doSomething is ONLY called by code in a ChildB object, and the code
for doSomething ONLY exists in a ChildA object? Then why not remove getA
from ParentB? It's never called, and it's not properly overriden. You only
need a virtual function if you're planning on using polymorphism to execute
the appropriate function via a base class reference or pointer.

Alternatively, you could add a virtual ParentA::doSomething(). That would
allow you to return a ParentA reference, and call doSomething on it.

Or use dynamic_cast.

If none of those ideas help, you might post a more complete example,
including the code that calls getA (and perhaps even the code within getA).

-Howard

Mar 8 '06 #11

P: n/a
On Wed, 08 Mar 2006 23:38:00 GMT, "Howard" <al*****@hotmail.com>
wrote:

"ctor" <blhbalh@.balh> wrote in message
news:jh********************************@4ax.com.. .
On Wed, 08 Mar 2006 20:55:08 GMT, "Howard" <al*****@hotmail.com>
wrote:

"ctor" <blhbalh@.balh> wrote in message
news:bv********************************@4ax.com ...
On Wed, 08 Mar 2006 19:23:27 GMT, "Howard" <al*****@hotmail.com>
wrote:
>> Hi Howard, thanks for the response. Unfortunately that won't suit my
>> purposes because ChildB::getA() is a function that only gets called by
>> ChildB itself. ChildB knows that it should be getting a ChildA
>> reference, and so it expects to be able to use ChildA's extended
>> interface.
>
>But it can! That's what polymorphism is all about. You don't show the
>definition of getA(), but if it constructs (or otherwise obtains) a
>ChildA
>object, then referring to it via a ParentA reference (or pointer) is
>perfectly valid.
>
>If you need to refer to members which exist ONLY in the ChildA object,
>then
>you can use dynamic_cast on the returned reference where needed.
>
>If you don't want to return a ParentA& reference from getA(), then why
>did
>you make it a virtual function in ParentB in the first place?
>
>-Howard
>

Thanks.

I didn't want to use a dynamic_cast because getA() will be called very
frequently (several hundred times per second).

That's not very frequently, and I doubt the cost of several hundred
dynamic_casts would be very high. (I'm not familiar with exactly how it's
accomplished, however.) Have you profiled the use of dynamic cast, and
seen
that it causes problems?
If you're not familiar with it, why are you giving me a lecture?


Have you profiled the use of dynamic cast, and seen that it _actually_
causes problems for you? If not, why are you assuming it will be a
significant problem? There's a common saying here: "Premature optimization
is the root of all evil."


No argument here. You're right that I haven't determined that
dynamic_cast would be a bottleneck in my program, and I apologize for
coming across aggressively.


I declared "virtual ParentA& ParentB::getA()" because ParentB needs to
call this function and use the interface pf the returned ParentA
reference.
Then why is ParentB::getA() _pure_ virtual, if ParentB needs to call it?
Obviously ParentB is an abstract class, so when I say ParentB needs to
call getA(), I'm talking about a sub-object ParentB within a ChildB
object.
And what's the problem using a ChildB reference as it if were a reference
to
a ParentB object? Every ChildB object IS A ParentB object.


The ChildA class has a public function "doSomething()" that ParentA
doesn't have.

ChildB needs to call getA().doSomething();


So... doSomething is ONLY called by code in a ChildB object, and the code
for doSomething ONLY exists in a ChildA object? Then why not remove getA
from ParentB? It's never called, and it's not properly overriden. You only
need a virtual function if you're planning on using polymorphism to execute
the appropriate function via a base class reference or pointer.


ParentB does call getA(), and it modifies the returned object via
ParentA's interface. ChildB calls getA() and modifies the returned
object via ChildA's interface. The reason I am using this design is
that there will be classes that are siblings of ChildB whose getA()
functions return siblings of ChildA. In ChildB and all of its
siblings, ParentB takes care of the same generic stuff that applies to
ParentA objects.

Alternatively, you could add a virtual ParentA::doSomething(). That would
allow you to return a ParentA reference, and call doSomething on it.

Or use dynamic_cast.

If none of those ideas help, you might post a more complete example,
including the code that calls getA (and perhaps even the code within getA).
Actually, I think I have the issue sorted out. My solution wouldn't
be very enlightening without posting my code in its entirely, however.

Thanks.
-Howard


Mar 9 '06 #12

P: n/a
By the way, if "ChildB knows that it should be getting a ChildA..."
then there's no need for dynamic_cast. Simple static_cast could[and
should] be used.

Regards,
Andrei

ctor wrote:
On Wed, 08 Mar 2006 19:03:17 GMT, "Howard" <al*****@hotmail.com>
wrote:

"ctor" <blhbalh@.balh> wrote in message
news:u4********************************@4ax.com.. .
Hi,

I'm experiencing an annoying issue. Here is a simplified idea of what
I am trying to do. Inclusion guards aren't shown for readability. I
hope this isn't too confusing; I don't think a description would be as
clear as an example.

-----[ParentA.h]------
class ParentA {};

-----[ChildA.h]------
#include "ParentA.h"
#include "ChildB.h"
class ChildA: public ParentA { ChildB foo; };

-----[ParentB.h]------
class ParentA;
class ParentB {
virtual ParentA& getA() = 0;
};

-----[ChildB.h]------
#include "ParentB.h"
class ChildA;
class ChildB: public ParentB {
ChildA& getA();
};

---


Why not return a ParentA& from ChildB::getA(), just like you do in
ParentB::getA()? You're returning a reference, so polymorphism will come
into play, and any calls to virtual functions in the returned ParentA object
will correctly execute their ChildA counterparts. And by publicly
inheriting, you've said that ChildA "is a" ParentA, so there shouldn't be
any problem. Any reason this idea won't work?

-Howard


Hi Howard, thanks for the response. Unfortunately that won't suit my
purposes because ChildB::getA() is a function that only gets called by
ChildB itself. ChildB knows that it should be getting a ChildA
reference, and so it expects to be able to use ChildA's extended
interface.


Mar 9 '06 #13

P: n/a

"Andrei Zavidei" <an************@gmail.com> wrote in message
news:11**********************@e56g2000cwe.googlegr oups.com...
By the way, if "ChildB knows that it should be getting a ChildA..."
then there's no need for dynamic_cast. Simple static_cast could[and
should] be used.

Regards,
Andrei


You're correct, of course.

-Howard
Mar 9 '06 #14

This discussion thread is closed

Replies have been disabled for this discussion.