我刚开始用 C++ 编程,我尝试创建 2 个类,其中一个将包含另一个。
文件 A.h
:
#ifndef _A_h
#define _A_h
class A{
public:
A(int id);
private:
int _id;
B _b; // HERE I GET A COMPILATION ERROR: B does not name a type
};
#endif
文件 A.cpp
:
#include "A.h"
#include "B.h"
#include <cstdio>
A::A(int id): _id(id), _b(){
printf("hello\n the id is: %d\n", _id);
}
文件 B.h
:
#ifndef _B_h
#define _B_h
class B{
public:
B();
};
#endif
文件 B.cpp
:
#include "B.h"
#include <cstdio>
B::B(){
printf("this is hello from B\n");
}
我首先编译 B 类,然后编译 A 类,但随后我收到错误消息:
Ah:9: 错误:’B’ 没有命名类型
我该如何解决这个问题?
原文由 or.nomore 发布,翻译遵循 CC BY-SA 4.0 许可协议
预处理器将文件
A.h
和B.h
的内容插入到include
语句出现的位置(这实际上只是复制/粘贴)。当编译器随后解析A.cpp
时,它会在知道类B
A
之前找到类 --- 的声明。这会导致您看到的错误。有两种方法可以解决这个问题:B.h
在A.h
。在需要的文件中包含头文件通常是一个好主意。如果您依赖于通过另一个标头间接包含,或者在编译单元(cpp 文件)中包含特殊顺序,那么随着项目变得越来越大,这只会使您和其他人感到困惑。B
类中使用A
类型的成员变量,编译器需要知道B
的准确和完整声明,因为它需要创建内存A
的布局。另一方面,如果您使用的是指向B
的指针或引用,那么前向声明就足够了,因为编译器需要为指针或引用保留的内存与类定义无关。这看起来像这样:这对于避免标头之间的循环依赖非常有用。
我希望这有帮助。