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

Discussion in 'C++' started by ctor, Mar 8, 2006.

  1. ctor

    ctor Guest

    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.
     
    ctor, Mar 8, 2006
    #1
    1. Advertising

  2. ctor

    Howard Guest

    "ctor" <blhbalh@.balh> wrote in message
    news:...
    > 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
     
    Howard, Mar 8, 2006
    #2
    1. Advertising

  3. ctor

    ctor Guest

    On Wed, 08 Mar 2006 19:03:17 GMT, "Howard" <>
    wrote:

    >
    >"ctor" <blhbalh@.balh> wrote in message
    >news:...
    >> 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.
     
    ctor, Mar 8, 2006
    #3
  4. ctor

    Howard Guest

    "ctor" <blhbalh@.balh> wrote in message
    news:...
    > On Wed, 08 Mar 2006 19:03:17 GMT, "Howard" <>
    > wrote:
    >
    >>
    >>"ctor" <blhbalh@.balh> wrote in message
    >>news:...
    >>> 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
     
    Howard, Mar 8, 2006
    #4
  5. ctor

    ctor Guest

    On Wed, 08 Mar 2006 19:23:27 GMT, "Howard" <>
    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?
     
    ctor, Mar 8, 2006
    #5
  6. ctor

    Neil Cerutti Guest

    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
     
    Neil Cerutti, Mar 8, 2006
    #6
  7. ctor

    Neil Cerutti Guest

    On 2006-03-08, Neil Cerutti <> 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
     
    Neil Cerutti, Mar 8, 2006
    #7
  8. ctor

    Howard Guest

    "ctor" <blhbalh@.balh> wrote in message
    news:...
    > On Wed, 08 Mar 2006 19:23:27 GMT, "Howard" <>
    > 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
     
    Howard, Mar 8, 2006
    #8
  9. ctor

    ctor Guest

    On Wed, 08 Mar 2006 20:55:08 GMT, "Howard" <>
    wrote:

    >
    >"ctor" <blhbalh@.balh> wrote in message
    >news:...
    >> On Wed, 08 Mar 2006 19:23:27 GMT, "Howard" <>
    >> 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();
     
    ctor, Mar 8, 2006
    #9
  10. ctor

    ctor Guest

    On 8 Mar 2006 20:59:10 +0100, Neil Cerutti <>
    wrote:

    >On 2006-03-08, Neil Cerutti <> 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();
    >> };
     
    ctor, Mar 8, 2006
    #10
  11. ctor

    Howard Guest

    "ctor" <blhbalh@.balh> wrote in message
    news:...
    > On Wed, 08 Mar 2006 20:55:08 GMT, "Howard" <>
    > wrote:
    >
    >>
    >>"ctor" <blhbalh@.balh> wrote in message
    >>news:...
    >>> On Wed, 08 Mar 2006 19:23:27 GMT, "Howard" <>
    >>> 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
     
    Howard, Mar 8, 2006
    #11
  12. ctor

    ctor Guest

    On Wed, 08 Mar 2006 23:38:00 GMT, "Howard" <>
    wrote:

    >
    >"ctor" <blhbalh@.balh> wrote in message
    >news:...
    >> On Wed, 08 Mar 2006 20:55:08 GMT, "Howard" <>
    >> wrote:
    >>
    >>>
    >>>"ctor" <blhbalh@.balh> wrote in message
    >>>news:...
    >>>> On Wed, 08 Mar 2006 19:23:27 GMT, "Howard" <>
    >>>> 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
    >
    >
    >
    >
     
    ctor, Mar 9, 2006
    #12
  13. 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" <>
    > wrote:
    >
    > >
    > >"ctor" <blhbalh@.balh> wrote in message
    > >news:...
    > >> 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.
     
    Andrei Zavidei, Mar 9, 2006
    #13
  14. ctor

    Howard Guest

    "Andrei Zavidei" <> wrote in message
    news:...
    > 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
     
    Howard, Mar 9, 2006
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page