Thread: Forward declaration of classes

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445

    Forward declaration of classes

    I have two classes: we'll call them A and B for the sake of discussion.

    B is publicly derived from A.
    a member function in A returns an instance of B.

    I can't get it to compile, even with forward declarations of these classes.

    is this even possible? I'm having a lot of trouble wrapping my head around this, and could use some help.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    a member function in A returns an instance of B.
    That's not possible, methinks, and is probably a bad design decision to begin with. The problem is that for the inheritance to work, A must be defined before B is defined. But for A's member function to return an instance of B, B must be defined before A. This circular dependency cannot be broken. However, in the first place, A should not have a member function that returns an instance of B, thus forcing A to know of B.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    On the other hand, if As really should create Bs, then you are looking for a factory pattern, where unrelated object A has a method that makes Bs.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    There are times when the base class knows about the derived class (some forms of multiple dispatch require this). You'd want to take an output parameter by reference or return a pointer. Then you can use the forward declaration.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Is that function in A virtual and overridden in B?
    Does it return an object, a reference or a pointer?

    Could you do this instead?
    Code:
    class A
    {
    public:
       virtual A*  GetDerivedClass() { return new A; }
    };
    
    class B : public A
    {
    public:
       virtual A*  GetDerivedClass() { return new B; }
    };

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Could you do this instead?
    It would probably be better to return a B* in B's override of GetDerivedClass(), but then I think we need a reply from Elkvis before we can begin giving more specific suggestions.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by laserlight View Post
    It would probably be better to return a B* in B's override of GetDerivedClass(), but then I think we need a reply from Elkvis before we can begin giving more specific suggestions.
    Then it wouldn't be an override (or at least not a good one), since you're changing the return type between the A & B version.
    If they need to call functions that are only in B and not in A, they could always do a:
    Code:
    B* pB = dynamic_cast<B*>( pA );

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Then it wouldn't be an override (or at least not a good one), since you're changing the return type between the A & B version.
    No, it would be a correct override, since B is-a A. This is just covariant return types at work.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> If they need to call functions that are only in B and not in A, they could always do a:
    VC++ 6.0 didn't handle covariant return types well, so you ended up being forced to use workarounds like that. It shouldn't be a problem any more.

  10. #10
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by laserlight View Post
    No, it would be a correct override, since B is-a A. This is just covariant return types at work.
    But then it would only return a B* if you're calling the function from a B class right? i.e. this wouldn't work:
    Code:
    A a;
    B* pB = a.GetDerivedClass();

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    But then it would only return a B* if you're calling the function from a B class right? i.e. this wouldn't work:
    Of course, but why should it work? Even if B's GetDerivedClass() returned an A*, your example still would not work, since A's GetDerivedClass() is called.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by laserlight View Post
    Of course, but why should it work? Even if B's GetDerivedClass() returned an A*, your example still would not work, since A's GetDerivedClass() is called.
    I'm not saying it should work with my way either, I'm just clearifying the implications for some less-experienced people that might be reading this.
    I guess (depending on how you plan to use these classes) it would be useful to have the B version return a B*.

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Basically, if you're calling from an A pointer, you usually expect an A* to be returned (since you're working generically anyway and probably don't know what a B is anyway).

    If you're calling from a B object or pointer, then you want a B* returned because that's what you're working with and you can always use it as an A if you really wanted to.

  14. #14
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    if you're calling B::getDerived directly from a B then you wouldn't need the function anyway, would you?

    if you're calling B::getDerived from an A, the return type will always be an A and need to be cast to B anyway.


    i don't see how it could possibly matter?

  15. #15
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    That example is too simple for it to matter, but factory and clone methods do basically the same thing and they do matter (you do sometimes need to call the method even if you already have a B).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. failure to import external C libraries in C++ project
    By nocturna_gr in forum C++ Programming
    Replies: 3
    Last Post: 12-02-2007, 03:49 PM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. Prime Number Generator... Help !?!!
    By Halo in forum C++ Programming
    Replies: 9
    Last Post: 10-20-2003, 07:26 PM
  4. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM
  5. Forward Declaration
    By BigDaddyDrew in forum C++ Programming
    Replies: 4
    Last Post: 02-01-2003, 12:15 PM