我刚开始用C ++编程,我试图创建两个类,其中一个将包含另一个。
档案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类,但后来我收到错误消息:
A.h:9:错误:'B'没有命名类型
如何解决此问题?
答案 0 :(得分:34)
预处理器将文件A.h
和B.h
的内容准确插入到include
语句出现的位置(这实际上只是复制/粘贴)。当编译器解析A.cpp
时,它会在知道类A
之前找到类B
的声明。这会导致您看到的错误。有两种方法可以解决这个问题:
B.h
中加入A.h
。将头文件包含在需要它们的文件中通常是个好主意。如果你依赖于通过另一个标题进行间接包含,或者在编译单元(cpp-file)中包含一个特殊的包含顺序,这只会让你和其他人混淆,因为项目变大了。如果在类B
中使用类型A
的成员变量,编译器需要知道B
的完整和完整声明,因为它需要创建内存-A
的布局。另一方面,如果您使用指针或B
的引用,则前向声明就足够了,因为编译器需要为指针或引用保留的内存与类定义无关。这看起来像这样:
class B; // forward declaration
class A {
public:
A(int id);
private:
int _id;
B & _b;
};
这对于避免标题之间的循环依赖非常有用。
我希望这会有所帮助。
答案 1 :(得分:3)
您必须先B.h
加入A.h
。 B b
;在你加入B.h
之前没有任何意义。
答案 2 :(得分:2)
在“A.h”中加入“B.h”。这会在编译'A'时为编译器声明'B'。
OP的第一个项目符号。
$ 3.4.1 / 7 -
“a。定义中使用的名称 成员函数之外的类X. body或嵌套类定义27) 应在其中一个中声明 以下方式:
- 在使用之前 class X或者是基类的成员 X(10.2),或
- 如果X是嵌套的 Y级(9.7)之前的类 在Y中定义X,或者应该是a Y基类的成员(这个 查找依次适用于Y. 封闭课程,从...开始 最里面的封闭类),28)或
- 如果 X是本地类(9.8)或是 之前的本地类的嵌套类 块中类X的定义 包含X类的定义, 或
- 如果X是命名空间N的成员, 或者是类的嵌套类 是N的成员,或者是本地班级 或本地类中的嵌套类 作为N的成员的函数, 在定义X类之前 名称空间N或N的一个封闭 命名空间“。
答案 3 :(得分:2)
问题是您需要在B.h
文件中加入A.h
。问题是在A
的定义中,编译器仍然不知道B
是什么。您应该包括您正在使用的所有类型的所有定义。
答案 4 :(得分:1)
当你定义A类时,在A.h中,你明确地说该类有一个成员B.
你必须在“A.h”中加入“Bah”
答案 5 :(得分:1)
你是否错过了A.h中的#include“B.h”?
答案 6 :(得分:1)
注意:由于使用相同关键字进行搜索的用户将进入此页面,因此我添加了此答案,这并不是上述情况下此编译器错误的原因。
当我在某个文件中声明一个enum
且其中一个元素的符号与类名相同的符号时,我遇到了这个错误。
例如如果我在某个文件中声明了enum = {A, B, C}
,而该文件又在另一个文件中声明了class A
的对象。
这引发了相同的编译器错误消息,提到了Class A does not name a type
。在我的情况下,没有循环依赖。
因此,在使用C ++命名类和声明枚举(在其他文件中可能是可见的,导入的和在外部使用的枚举)时要小心。
答案 7 :(得分:0)
今天我的问题的解决方案与这里的其他回答略有不同。
就我而言,问题是由包含链中的头文件之一结尾处缺少右括号(}
)引起的。
从本质上讲,正在发生的事情是A
包含B
。由于B
在文件中某处缺少}
,因此在B
中找不到正确的A
中的定义。
起初,我认为我有循环依赖关系,并添加了前向声明B
。但是随后,它开始抱怨B
中的某些内容是不完整的类型。这就是我想仔细检查文件中语法错误的方式。
答案 8 :(得分:-1)
实际上发生在我身上,是因为我错误地将源文件命名为“ something.c” 而不是“ something.cpp”。 希望这对有相同错误的人有所帮助。