Confusion over including header files...Can you give me a quick hand?

Discussion in 'C++' started by Eternally, Jul 11, 2003.

  1. Eternally

    Eternally Guest

    Ok, this may sound confusing....but it's really simple. If you're confused,
    just look at my example code and it'll make sense.

    Here's my situation. I have 2 classes....A and B.

    Class A has a member variable of type B.
    Class B has a member function which does calculations which are dependent
    upon values of members of the Class A that owns it.

    When in that function of class B, I don't know how I can gain access to it's
    parent Class A's member variables, so my solution to the problem is to take
    as a parameter to that function, a class A datatype. So, it's like this:

    class A
    {
    public:
    int x;
    B myB;
    :
    :
    };

    class B
    {
    public:
    int y;
    void theFunction(A parentA);
    :
    :
    };

    void B::theFunction(A parentA){
    y = parentA.x * 10;
    }

    I would call it like this:
    A myA;
    myA.myB(myA);

    Now, the problem is, both A.h and B.h have to include eachother. When they
    do, I get the following compilation errors:
    A.h(10): error C2143: syntax error : missing ';' before 'B'
    A.h(10): error C2501: 'A::B' : missing storage-class or type specifiers

    Line 10 is the line that I declare B myB is A.h.

    If I comment out theFunction in B and I comment out the include of A.h,
    it'll compile no problem. But that obviously isn't the solution as B can't
    use A.

    So, I need one of 2 solutions. Either (and most preferably) I somehow gain
    access to the parent object A's member variables, without having to pass A
    as a parameter to B's function....or, I keep it like it is, but somehow get
    it to compile.

    Can anyone inform me how either of the above can be accomplished?

    Oh...and I know I could just pass myA.x, but don't want to do that as the
    real function is called often and is actually dependent upon many member
    variables of A.

    Thanks a lot for any help!
    Eternally, Jul 11, 2003
    #1
    1. Advertising

  2. "Eternally" <> wrote...
    > Ok, this may sound confusing....but it's really simple. If you're

    confused,
    > just look at my example code and it'll make sense.
    >
    > Here's my situation. I have 2 classes....A and B.
    >
    > Class A has a member variable of type B.
    > Class B has a member function which does calculations which are dependent
    > upon values of members of the Class A that owns it.
    >
    > When in that function of class B, I don't know how I can gain access to

    it's
    > parent Class A's member variables, so my solution to the problem is to

    take
    > as a parameter to that function, a class A datatype.


    That's one way to do it...

    An alternative way would be to pass the 'A*' during construction
    of the member B, and then B will always know where its parent is.

    > So, it's like this:
    >
    > class A
    > {
    > public:
    > int x;
    > B myB;
    > :
    > :
    > };
    >
    > class B
    > {
    > public:
    > int y;
    > void theFunction(A parentA);


    I wouldn't pass by value, of course. It is better to pass by
    reference, for example. All you need to declare is that 'A' is
    a class, really. This should help:

    void theFunction(class A parentA);

    and you don't need to include the declaration of A.

    > :
    > :
    > };
    >
    > void B::theFunction(A parentA){
    > y = parentA.x * 10;
    > }
    >
    > I would call it like this:
    > A myA;
    > myA.myB(myA);
    >
    > Now, the problem is, both A.h and B.h have to include eachother. When

    they
    > do, I get the following compilation errors:
    > A.h(10): error C2143: syntax error : missing ';' before 'B'
    > A.h(10): error C2501: 'A::B' : missing storage-class or type specifiers
    >
    > Line 10 is the line that I declare B myB is A.h.
    >
    > If I comment out theFunction in B and I comment out the include of A.h,
    > it'll compile no problem. But that obviously isn't the solution as B

    can't
    > use A.
    >
    > So, I need one of 2 solutions. Either (and most preferably) I somehow

    gain
    > access to the parent object A's member variables, without having to pass A
    > as a parameter to B's function....or, I keep it like it is, but somehow

    get
    > it to compile.


    See above. The alternative solution I was talking about is to
    declare 'B's constructor as accepting A&:

    class A; // forward declataion
    class B {
    A& parent;
    public:
    B(A& p) : parent(p);
    };

    ....
    class A {
    B myB;
    public:
    A() : myB(*this) {}
    ...
    };

    The compiler may not line the use of 'this' in the initialiser list,
    but you can ignore the warning.

    > Can anyone inform me how either of the above can be accomplished?
    >
    > Oh...and I know I could just pass myA.x, but don't want to do that as the
    > real function is called often and is actually dependent upon many member
    > variables of A.


    Shouldn't it be a member of A, then?

    Victor
    Victor Bazarov, Jul 11, 2003
    #2
    1. Advertising

  3. Eternally

    Eternally Guest

    "Victor Bazarov" <> wrote in message
    news:...
    > "Eternally" <> wrote...
    > > Ok, this may sound confusing....but it's really simple. If you're

    > confused,
    > > just look at my example code and it'll make sense.
    > >
    > > Here's my situation. I have 2 classes....A and B.
    > >
    > > Class A has a member variable of type B.
    > > Class B has a member function which does calculations which are

    dependent
    > > upon values of members of the Class A that owns it.
    > >
    > > When in that function of class B, I don't know how I can gain access to

    > it's
    > > parent Class A's member variables, so my solution to the problem is to

    > take
    > > as a parameter to that function, a class A datatype.

    >
    > That's one way to do it...
    >
    > An alternative way would be to pass the 'A*' during construction
    > of the member B, and then B will always know where its parent is.
    >
    > > So, it's like this:
    > >
    > > class A
    > > {
    > > public:
    > > int x;
    > > B myB;
    > > :
    > > :
    > > };
    > >
    > > class B
    > > {
    > > public:
    > > int y;
    > > void theFunction(A parentA);

    >
    > I wouldn't pass by value, of course. It is better to pass by
    > reference, for example. All you need to declare is that 'A' is
    > a class, really. This should help:
    >
    > void theFunction(class A parentA);
    >
    > and you don't need to include the declaration of A.
    >
    > > :
    > > :
    > > };
    > >
    > > void B::theFunction(A parentA){
    > > y = parentA.x * 10;
    > > }
    > >
    > > I would call it like this:
    > > A myA;
    > > myA.myB(myA);
    > >
    > > Now, the problem is, both A.h and B.h have to include eachother. When

    > they
    > > do, I get the following compilation errors:
    > > A.h(10): error C2143: syntax error : missing ';' before 'B'
    > > A.h(10): error C2501: 'A::B' : missing storage-class or type specifiers
    > >
    > > Line 10 is the line that I declare B myB is A.h.
    > >
    > > If I comment out theFunction in B and I comment out the include of A.h,
    > > it'll compile no problem. But that obviously isn't the solution as B

    > can't
    > > use A.
    > >
    > > So, I need one of 2 solutions. Either (and most preferably) I somehow

    > gain
    > > access to the parent object A's member variables, without having to pass

    A
    > > as a parameter to B's function....or, I keep it like it is, but somehow

    > get
    > > it to compile.

    >
    > See above. The alternative solution I was talking about is to
    > declare 'B's constructor as accepting A&:
    >
    > class A; // forward declataion
    > class B {
    > A& parent;
    > public:
    > B(A& p) : parent(p);
    > };
    >
    > ...
    > class A {
    > B myB;
    > public:
    > A() : myB(*this) {}
    > ...
    > };
    >
    > The compiler may not line the use of 'this' in the initialiser list,
    > but you can ignore the warning.
    >
    > > Can anyone inform me how either of the above can be accomplished?
    > >
    > > Oh...and I know I could just pass myA.x, but don't want to do that as

    the
    > > real function is called often and is actually dependent upon many member
    > > variables of A.

    >
    > Shouldn't it be a member of A, then?
    >
    > Victor
    >
    >


    Hi,

    That's a nice solution, and I'll probably use it, but the problem still is
    that even if I comment out theFunction in B and all references to A, as long
    as B is including A.h, those compiler errors still remain. If I comment out
    #include "A.h", then it compiles without errors....but if I put it in the
    errors come back.

    If A.h includes B.h and B.h includes A.h, then those errors will be there.

    Thanks for the help!
    Eternally, Jul 12, 2003
    #3
  4. "Eternally" <> wrote...
    > [...]
    > That's a nice solution, and I'll probably use it, but the problem still is
    > that even if I comment out theFunction in B and all references to A, as

    long
    > as B is including A.h, those compiler errors still remain. If I comment

    out
    > #include "A.h", then it compiles without errors....but if I put it in the
    > errors come back.


    "Doctor, if I do this, it hurts. What should I do?"
    "Don't do that."

    > If A.h includes B.h and B.h includes A.h, then those errors will be there.


    Of course. The solution is not to have those circular includes.

    Victor
    Victor Bazarov, Jul 12, 2003
    #4
  5. Eternally

    Ellarco Guest

    "Eternally" <> wrote in message
    news:k7FPa.33262$...
    > Ok, this may sound confusing....but it's really simple. If you're

    confused,
    > just look at my example code and it'll make sense.
    >
    > Here's my situation. I have 2 classes....A and B.
    >
    > Class A has a member variable of type B.
    > Class B has a member function which does calculations which are dependent
    > upon values of members of the Class A that owns it.
    >
    > When in that function of class B, I don't know how I can gain access to

    it's
    > parent Class A's member variables, so my solution to the problem is to

    take
    > as a parameter to that function, a class A datatype. So, it's like this:
    >
    > class A
    > {
    > public:
    > int x;
    > B myB;
    > :
    > :
    > };
    >
    > class B
    > {
    > public:
    > int y;
    > void theFunction(A parentA);
    > :
    > :
    > };
    >
    > void B::theFunction(A parentA){
    > y = parentA.x * 10;
    > }
    >
    > I would call it like this:
    > A myA;
    > myA.myB(myA);
    >
    > Now, the problem is, both A.h and B.h have to include eachother. When

    they
    > do, I get the following compilation errors:
    > A.h(10): error C2143: syntax error : missing ';' before 'B'
    > A.h(10): error C2501: 'A::B' : missing storage-class or type specifiers
    >
    > Line 10 is the line that I declare B myB is A.h.
    >
    > If I comment out theFunction in B and I comment out the include of A.h,
    > it'll compile no problem. But that obviously isn't the solution as B

    can't
    > use A.
    >
    > So, I need one of 2 solutions. Either (and most preferably) I somehow

    gain
    > access to the parent object A's member variables, without having to pass A
    > as a parameter to B's function....or, I keep it like it is, but somehow

    get
    > it to compile.
    >
    > Can anyone inform me how either of the above can be accomplished?
    >
    > Oh...and I know I could just pass myA.x, but don't want to do that as the
    > real function is called often and is actually dependent upon many member
    > variables of A.
    >
    > Thanks a lot for any help!
    >
    >


    Something I have done in the face of circular dependencies is as illustrated
    below. Im not especialy proud of it but it worked. If anyone has comments on
    the technique Id be glad to hear them.

    ---- A.h ----

    #ifndef A_H
    #define A_H

    class B; /* #include "B.h" */

    class A
    { private:
    B myB;
    ....
    };
    .....

    /**
    * By this point itll be possible to define the
    * B class since A has already been defined
    */
    #include "B.h"

    #endif

    ---- B.h ----

    #ifndef B_H
    #define B_H

    #include "A.h"

    class B
    { public:
    void theFunction(A*);
    ....
    };
    .....

    #endif
    ----
    Ellarco, Jul 12, 2003
    #5
  6. Eternally

    John Ericson Guest

    "Ellarco" <> wrote in message
    news:1pRPa.22683$...
    >
    > "Eternally" <> wrote in message
    > news:k7FPa.33262$...
    > > Ok, this may sound confusing....but it's really simple.

    If you're
    > confused,
    > > just look at my example code and it'll make sense.
    > >
    > > Here's my situation. I have 2 classes....A and B.
    > >
    > > Class A has a member variable of type B.
    > > Class B has a member function which does calculations

    which are dependent
    > > upon values of members of the Class A that owns it.
    > >
    > > When in that function of class B, I don't know how I can

    gain access to
    > it's
    > > parent Class A's member variables, so my solution to the

    problem is to
    > take
    > > as a parameter to that function, a class A datatype.

    So, it's like this:
    > >
    > > class A
    > > {
    > > public:
    > > int x;
    > > B myB;
    > > :
    > > :
    > > };
    > >
    > > class B
    > > {
    > > public:
    > > int y;
    > > void theFunction(A parentA);
    > > :
    > > :
    > > };
    > >
    > > void B::theFunction(A parentA){
    > > y = parentA.x * 10;
    > > }
    > >
    > > I would call it like this:
    > > A myA;
    > > myA.myB(myA);
    > >
    > > Now, the problem is, both A.h and B.h have to include

    eachother. When
    > they
    > > do, I get the following compilation errors:
    > > A.h(10): error C2143: syntax error : missing ';' before

    'B'
    > > A.h(10): error C2501: 'A::B' : missing storage-class or

    type specifiers
    > >
    > > Line 10 is the line that I declare B myB is A.h.
    > >
    > > If I comment out theFunction in B and I comment out the

    include of A.h,
    > > it'll compile no problem. But that obviously isn't the

    solution as B
    > can't
    > > use A.
    > >
    > > So, I need one of 2 solutions. Either (and most

    preferably) I somehow
    > gain
    > > access to the parent object A's member variables,

    without having to pass A
    > > as a parameter to B's function....or, I keep it like it

    is, but somehow
    > get
    > > it to compile.
    > >
    > > Can anyone inform me how either of the above can be

    accomplished?
    > >
    > > Oh...and I know I could just pass myA.x, but don't want

    to do that as the
    > > real function is called often and is actually dependent

    upon many member
    > > variables of A.
    > >
    > > Thanks a lot for any help!
    > >
    > >

    >
    > Something I have done in the face of circular dependencies

    is as illustrated
    > below. Im not especialy proud of it but it worked. If

    anyone has comments on
    > the technique Id be glad to hear them.
    >
    > ---- A.h ----
    >
    > #ifndef A_H
    > #define A_H
    >
    > class B; /* #include "B.h" */
    >
    > class A
    > { private:
    > B myB;
    > ....
    > };
    > ....
    >
    > /**
    > * By this point itll be possible to define the
    > * B class since A has already been defined
    > */
    > #include "B.h"
    >
    > #endif
    >
    > ---- B.h ----
    >
    > #ifndef B_H
    > #define B_H
    >
    > #include "A.h"
    >
    > class B
    > { public:
    > void theFunction(A*);
    > ....
    > };
    > ....
    >
    > #endif
    > ----
    >


    You've got the forward declaration and #include-in-header
    backwards.
    John Ericson, Jul 12, 2003
    #6
  7. "TR" <> writes:

    > "Victor Bazarov" <> wrote in message
    > news:pNKPa.37554$...
    > > > If A.h includes B.h and B.h includes A.h, then those errors will be

    > there.
    > >
    > > Of course. The solution is not to have those circular includes.

    >
    > A better long-term solution is header guards, unless this is the most
    > complex program he's ever going to create.
    >
    > Use this in your A.h and B.h files:
    >
    > #ifndef FILENAME_H
    > #define FILENAME_H
    >
    > contents of header
    >
    > #endif
    >
    > or in VC++ just:
    > #pragma once
    >
    > at the top. But it's less portable.


    Huh? Include guards don't prevent circular includes - have you
    actually *READ* the thread?

    regards
    frank

    --
    Frank Schmitt
    4SC AG phone: +49 89 700763-0
    e-mail: frank DOT schmitt AT 4sc DOT com
    Frank Schmitt, Jul 14, 2003
    #7
  8. Eternally

    mjm Guest

    I haven't read the whole thread -- so I am sorry if the question has
    been answered already.

    When the class A is declared in a header pointer members of A need not
    have been defined (only declared) a this point:

    file A.h:

    class B; // forward declaration

    class A {

    B* b;
    int f(B x);
    }


    The forward declaration allows you to use the name "B"
    as a type name, A.h need not include B.h.
    The class B has to be defined somewhere of course.
    You cannot USE B in the header, ie. this won't work

    class A {

    B* b;
    int f(B x){ return b.doSomething(); }

    }

    But if the header contains only declarations and no implementations
    that problem does not occur. You move the definition of A::f to A.cc
    and #include B.h in A.cc.
    mjm, Jul 17, 2003
    #8
    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.
Similar Threads
  1. give me ur hand

    , Apr 11, 2006, in forum: Java
    Replies:
    2
    Views:
    332
    Roedy Green
    Apr 11, 2006
  2. dharmesh Gupta

    Confusion over header files

    dharmesh Gupta, Aug 11, 2003, in forum: C++
    Replies:
    5
    Views:
    525
    dharmesh Gupta
    Aug 14, 2003
  3. heab92
    Replies:
    0
    Views:
    359
    heab92
    Aug 20, 2007
  4. mlt
    Replies:
    2
    Views:
    831
    Jean-Marc Bourguet
    Jan 31, 2009
  5. BlackSabbath

    give the hand to an external application

    BlackSabbath, Jul 9, 2003, in forum: Javascript
    Replies:
    1
    Views:
    83
    David Dorward
    Jul 9, 2003
Loading...

Share This Page