accessing class problem

Ok,
let's assume that I've written a class in a file for example A.h:
1
2
3
4
class A
{
  int a;
};


and I create another class that contains A (in file B.h) for example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "A.h"
#include <iostream>
#include <vector>
class B
{
  std::vector<A> avec;
  syd::vector<int> getAmembers() {
    std::vector<int> members;
    for(int i=0; i<avec.size(); i++)
      members.push_back(avec[i].a);
    
    return members;
  }
}


now i need to add a pointer of class B in class A to access the method provided in class B like this:
1
2
3
4
5
class A
{
  int a;
  B* bptr;
};


and of course it needs the class B to be included in A.h. but surely compiler won't accept it that two files include each other. so how can i solve this problem?

Forward declaration. You declare the existence of class B before the definition of class A, so that A can contain a pointer to such an object.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <vector>
 
class B;
 
class A
{
  public:
  int a;
  B* bptr;
};
 
 
 
class B
{
  std::vector<A> avec;
  std::vector<int> getAmembers() {
    std::vector<int> members;
    for(int i=0; i<avec.size(); i++)
      members.push_back(avec[i].a);
    
    return members;
  }
};
 
int main()
{
  A objectOfTypeA;
  B objectOfTypeB;
  objectOfTypeA.bptr = &objectOfTypeB;
  return 0;
} 

Last edited on
so you say i should write both classes in a single file?
You don't have to; you just need to ensure that by the time the compiler gets to the definition of the class A, it knows that class B will be defined, and vice-versa.

However, since you're always going to need class A defined if you want to use class B, and vice-versa, it would make it easier for you to keep track of them if you put them in the same file, and it means you will only have one file to include if you want to use them.
Last edited on
Ok, I wrote this:

A.h:
1
2
3
4
5
6
7
8
9
10
#include "B.h"

class B;
 
class A
{
  public:
  int a;
  B* bptr;
};


B.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <vector>
#include "A.h"

class A;

class B
{
  std::vector<A> avec;
  std::vector<int> getAmembers() {
    std::vector<int> members;
    for(int i=0; i<avec.size(); i++)
      members.push_back(avec[i].a);  //error here
    
    return members;
  }
};


main.cpp:
1
2
3
4
5
6
7
8
9
10
#include "A.h"

 
int main()
{
  A objectOfTypeA;
  B objectOfTypeB;
  objectOfTypeA.bptr = &objectOfTypeB;
  return 0;
} 


And i got these error:
Error 2 error C2027: use of undefined type 'A' (b.h line 16)
Error 3 error C2228: left of '.a' must have class/struct/union (b.h line 16)

Thanks for answering ;)
Firstly, I see that you #include A.h, and that #includes B.h, and that #includes A.h, and that #includes B.h, and that #includes A.h, and that #includes B.h, and that #includes A.h, and that #includes B.h, and that #includes A.h, and that #includes B.h, and that #includes A.h... and so on forever. This is bad, and I'm surprised that your compiler doesn't just refuse to compile this infinite loop. Use header guards to prevent these infinite loops.

So, on to the errors. In your class B, you are trying to use the definiton of class A - you're trying to make a vector of them, so your class B needs to know how much space to use. However, this is impossible - at this point, the compiler has not seen the definition of class A so cannot know how much space to allocate. It could have a pointer, because a pointer takes up the same amount of space for anything it points to, which is why the pointer in class B works.

So, you need to make sure that by the time you're defining class B, the definition of class A has been seen by the compiler. If you remove that #include "B.h" at the top of A.h, it should work.
Now I see this, for header guard i took care of that i just didn't write them here. And removing that include just worked fine. Thanks a lot mate ;)
A question here, if i can't use the methods provided in class B in A something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <vector>
class B;
 
class A
{
  public:
  int a;
  B* bptr;

  std::vector<int> getMembers() {
    return B->getAmembers();
  }
};


then what's the point in keeping a pointer in that class?? What would you recommend if i need to do such a thing?
Ok, I got it now, it's the idea of understanding how compiler generates codes. I separated the source of method in a .cpp file and included B.h there this will work ;)

A.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef A_H_
#define A_H_
#include <iostream>
#include <vector>

class B;

class A
{
public:
  int a;
  B* bptr;

  std::vector<int> getMembers();
};

#endif 


A.cpp
1
2
3
4
5
6
#include "A.h"
#include "B.h"

std::vector<int> A::getMembers() {
  return bptr->getAmembers();
}
Topic archived. No new replies allowed.