Thread: "nested" classes

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    "nested" classes

    Hmm, I think I am out of luck here but still have to ask.

    Class A includes a member instance of class B.
    Class B includes a member instance of class A (actually just a pointer to the instance of A which owns it).

    There is no way to declare this, is there? I was hoping I could go:
    Code:
    class A;
    class B;
    
    class A { complete declaration }
    class B { complete declaration }
    but B referred to in A produces "error: field B has incomplete type"

    Maybe I can use a void pointer here for field B?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    One of them needs to be a pointer.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    You'll have to define B before A (since A has B as a member, but B doesn't have A as one).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by anon View Post
    You'll have to define B before A (since A has B as a member, but B doesn't have A as one).
    ... with, of course, the forward declaration of class A (i.e., when defining class B, the compiler doesn't need to know the details of class A, just that the name exists).

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    The problem with using a pointer is that C++ seemingly doesn't allow me to use "void*" here, so the pointer must be of a type.

    So class A must be defined before class B which must be defined before class A.

    Quote Originally Posted by tabstop View Post
    ... with, of course, the forward declaration of class A (i.e., when defining class B, the compiler doesn't need to know the details of class A, just that the name exists).
    Sure, but the forward declaration of A includes a member of type B (or a pointer of same type, void* is no good). I was hoping just this would be okay:
    Code:
    class A;
    class B:
    But I now think that is actually meaningless in C++ (it does not count for anything).
    Last edited by MK27; 03-31-2010 at 10:13 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You should know this from C: you cannot have A have a member of type B when B has a member of type A. You need to break this cyclic dependency with the use of a pointer or reference.
    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 Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by MK27 View Post
    The problem with using a pointer is that C++ seemingly doesn't allow me to use "void*" here, so the pointer must be of a type.

    So class A must be defined before class B which must be defined before class A.



    Sure, but the forward declaration of A includes a member of type B (or a pointer of same type, void* is no good). I was hoping just this would be okay:
    Code:
    class A;
    class B:
    But I now think that is actually meaningless in C++ (it does not count for anything).
    Again with the smoking things. You really should quit.
    Code:
    class A;
    class B {
        private:
            A* parent;
            int data;
    };
    
    class A {
        private:
            B child;
    };
    
    int main() {
        return 0;
    }
    is a perfectly good program.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by laserlight View Post
    You should know this from C: you cannot have A have a member of type B when B has a member of type A. You need to break this cyclic dependency with the use of a pointer or reference.
    Yeah, but in C I would just use a void pointer. Is there no equivalent of that?

    Related to this altho slightly theoretical right now, can I include a reference to self in an initializer list, eg:
    Code:
    A::A() : membB((void*)this) {
    Here the membB is initialized with a pointer to the instance of A that owns it.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by MK27
    Yeah, but in C I would just use a void pointer. Is there no equivalent of that?
    I would not use a void pointer in C for this case. See tabstop's post #7.

    Quote Originally Posted by MK27
    can I include a reference to self in an initializer list
    I am not sure. It should be safe to access this in the constructor body though. (EDIT: ah, I read too deeply into the text of the Standard at one point; in another point, the use of the this pointer in a constructor initialisation list was demonstrated, with caveats, so it is not just something that just happens to work with current compilers, assuming that you do not trip over the caveats.)
    Last edited by laserlight; 03-31-2010 at 10:34 AM.
    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

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    There is no reason to use void*, because you can have a pointer / reference to incomplete, forward-declared type.

    And yes, you can pass this, but the constructor of B needs to take into account that the A instance may not be fully constructed at that time. (You can store the pointer, but shouldn't do anything else with it.)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by tabstop View Post
    is a perfectly good program.
    Err, that is exactly what I tried to do the first time.

    Quote Originally Posted by MK27 View Post
    but B referred to in A produces "error: field B has incomplete type"
    Altho at that time it was not a pointer; I've been presuming a pointer would be subject to the same restriction as it's type.

    Quote Originally Posted by anon View Post
    There is no reason to use void*, because you can have a pointer / reference to incomplete, forward-declared type.
    But maybe not. Will try.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by MK27 View Post
    Altho at that time it was not a pointer; I've been presuming a pointer would be subject to the same restriction as it's type.
    It won't, since the compiler doesn't actually need to know how the class looks like if it's a pointer.
    It needs the definition if it is a mere member, as it must parse for constructors and the like (hence needs to actually see the contents of the class).

    So in the first, you can get away with a forward-declaration to merely tell the compiler the type exists. The definition only needs to be available when you implement the class.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you Initialize all classes once with New?
    By peacerosetx in forum C++ Programming
    Replies: 12
    Last Post: 07-02-2008, 10:47 AM
  2. Multiple Inheritance - Size of Classes?
    By Zeusbwr in forum C++ Programming
    Replies: 10
    Last Post: 11-26-2004, 09:04 AM
  3. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-23-2004, 11:22 PM
  4. Exporting VC++ classes for use with VB
    By Helix in forum Windows Programming
    Replies: 2
    Last Post: 12-29-2003, 05:38 PM
  5. Prime Number Generator... Help !?!!
    By Halo in forum C++ Programming
    Replies: 9
    Last Post: 10-20-2003, 07:26 PM