Using class A vectors in class B

I created class A and class B, and I'm trying to set a vector of type B to and a vector of type A to B:

Class A Title:

#ifndef A_H_ #define A_H_ #include "Bh" #include <vector> using namespace std; class A { public: vector<B> bvector; // here is the error A(); }; #endif /* A_H_ */ 

class B header:

 #ifndef B_H_ #define B_H_ #include "Ah" #include <vector> using namespace std; class B { vector<A> aVector; //Here is the error public: B(); }; #endif /* B_H_ */ 

But I get the following errors:

".. \ src / Bh: 16: 8: error:" A "was not declared in this area

.. \ src / Bh: 16: 9: error: template argument 1 is not valid

.. \ src / Bh: 16: 9: error: template argument 2 is not valid "

What flips to Ah if I delete the wrong line in B. What am I doing wrong?

+4
source share
3 answers

ive created class A and class B, im trying to set a vector of type B to and a vector of type A to B

You create a circular dependency between your classes. This is usually bad, especially in C ++.

The compiler to compile A must know the definition of B (#include "Bh"). Unfortunately, heading B contains a reference to class A (here a circular link). The compiler cannot handle this situation, since the header is already included in the current TU (see Include guard).

Although circular references are often a symptom of poor design, you can ultimately overcome the problem using a forward declaration. For example, you can change B as follows:

 #ifndef B_H_ #define B_H_ #include <vector> using namespace std; class A; //forward declaration of class A class B { vector<A*> aVector; //note that you must only use pointer to A now public: B(); }; #endif /* B_H_ */ 

Using a direct declaration basically tells the compiler that type A will be defined somewhere else. The compiler can rely on this fact, but it knows nothing about A (in particular, it ignores the size of A and its methods). Therefore, inside B, if you have A declared forward, you can only use pointers to classes A (pointers always have the same size), and you cannot call any methods of class A from the inside.

+2
source

The trick is that you need to forward the announcement of one of the two classes. Unfortunately, advanced declarations will not allow you to use the full type of the header - they will allow you to use a pointer to that type. So even in this case it will not work.

You can use the PIMPL idiom (pointer to IMPLementation) (google) to get around this problem.

The PIMPL idiom will basically create the third type. Then your type B will contain a pointer to an implementation class containing a vector of type A. All operations of the vector that should have been stored in B will be redirected to a new implementation class that actually contained the vector A.

For instance:

 //Forward declare impl class. class BImpl; class B { private: BImpl* impl; public: void PrintVector() { impl->PrintVector(); } }; class A { private: std::vector<B> vec; public: void PrintVector() { /* Do printing */ } }; class BImpl { private: std::vector<A> vec; public: void PrintVector() { /* Do Printing */ } }; 

I did not include constructors or population methods for these classes, but you should get a general idea :)

+1
source

You have a circular dependency.

Ah includes Bh , which includes Ah , but the protection A_H_ already defined, so the contents of Ah skipped, therefore the contents of Bh processed, which is related to A but it is not yet defined, because you have not processed anything in Ah , except for the #define and #include directives at the top of Ah

0
source

Source: https://habr.com/ru/post/1444001/


All Articles