The error: 'xxx' does not name a type problem caused by mutual inclusion of forward declaration and C++ header file

In a source file, when you want to declare or define a pointer to a class, you must declare or define the class before using it, so the following code will report an error:

class A
{
public:
    B *b;
};

class B
{
public:
    A *a;
};

int main()
{
    return 0;
}


The error is "error: 'B' does not name a type", because there is no declaration or definition of class B before using B *b in class A. If you add a forward declaration (forward declaration) "class B;", there will be no such problem.
When the header files include each other, "error: 'xxx' does not name a type" will also be triggered. The reason for the error is the same as the above code. Please see the following code: ah
:

#ifndef A_H_INCLUDED
#define A_H_INCLUDED

#include "b.h"

class A
{
public:
    B *b;
};

#endif // A_H_INCLUDED


b.h:

#ifndef B_H_INCLUDED
#define B_H_INCLUDED

#include "a.h"

class B
{
public:
    A *a;
};

#endif // B_H_INCLUDED


main.cpp:

#include "a.h"
#include "b.h"

int main()
{
    return 0;
}


Compilation will report an error: "error: 'A' does not name a type", why is this happening? Let's see what ah will expand after preprocessing. The preprocessing command is "gcc -E -o ai ah":

# 1 "a.h"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.h"

# 1 "b.h" 1

# 1 "a.h" 1
# 5 "b.h" 2

class B
{
public:
    A *a;
};
# 5 "a.h" 2

class A
{
public:
    B *b;
};


Ignoring the line starting with "#", we found that it is now almost the same as the source file at the beginning, but the order of the classes is exchanged, so the cause of the error is the same as the source file at the beginning.
The solution is also very simple, replace the "#include "bh"" of ah with the pre-declaration "class B;" of class B, and make similar modifications in bh. That way, it won't cause problems. Of course, there is a prerequisite for doing this: the members in class A only have pointers to class B, but cannot have variables of class B; at the same time, you cannot access members or member functions of class B in the header file of class A. In either case, class A needs to know the size or other details of class B, and the forward declaration cannot provide these details, and problems like "error: field 'b' has incomplete type 'B'" will appear again.
 

Guess you like

Origin blog.csdn.net/weixin_58045467/article/details/130722016