类名未在C++中命名类型

or.*_*ore 29 c++

我刚开始用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
Run Code Online (Sandbox Code Playgroud)

档案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);
}
Run Code Online (Sandbox Code Playgroud)

档案B.h:

#ifndef _B_h
#define _B_h

class B{
    public:
        B();
};
#endif
Run Code Online (Sandbox Code Playgroud)

档案B.cpp:

#include "B.h"
#include <cstdio>

B::B(){
    printf("this is hello from B\n");
}
Run Code Online (Sandbox Code Playgroud)

我首先编译B类,然后编译A类,但后来我收到错误消息:

啊:9:错误:'B'没有命名类型

我该如何解决这个问题?

Bjö*_*lex 36

预处理器插入文件的内容A.h以及语句出现的B.h确切位置include(这实际上只是复制/粘贴).当编译器然后解析时A.cpp,它会A在知道类之前找到类的声明B.这会导致您看到的错误.有两种方法可以解决这个问题:

  1. 包括B.hA.h.将头文件包含在需要它们的文件中通常是个好主意.如果你依赖于通过另一个标题进行间接包含,或者在编译单元(cpp-file)中包含一个特殊的包含顺序,那么随着项目变大,这只会让你和其他人感到困惑.
  2. 如果B在类中使用类型的成员变量A,编译器需要知道完整和完整的声明B,因为它需要为其创建内存布局A.另一方面,如果您使用指针或引用B,那么前向声明就足够了,因为编译器需要为指针或引用保留的内存与类定义无关.这看起来像这样:

    class B; // forward declaration        
    class A {
    public:
        A(int id);
    private:
        int _id;
        B & _b;
    };
    
    Run Code Online (Sandbox Code Playgroud)

    这对于避免标头之间的循环依赖非常有用.

我希望这有帮助.


Iva*_*van 8

error 'Class' does not name a type
Run Code Online (Sandbox Code Playgroud)

万一有人做了同样的愚蠢的事我做了...我从头开始创建一个小的测试程序,我输入Class而不是class(用一个小C).我没有注意到错误消息中的引号,并花了一点时间不理解我的问题.

我寻找一个解决方案让我来到这里,所以我想其他人也会这样.


Ada*_*han 5

注意:因为使用相同关键字搜索的人将登陆此页面,所以我添加了这个答案,这不是上述情况下编译器错误的原因。

当我enum在某个文件中声明了一个与我的类名具有相同符号的元素时,我正面临这个错误。

例如,如果我enum = {A, B, C}在某个文件中声明了一个,该文件包含在另一个文件中,我在其中声明了class A.

这是抛出相同的编译器错误消息,提到Class A does not name a type. 在我的情况下没有循环依赖。

因此,在 C++ 中命名类和声明枚举(可能在其他文件中可见、导入和外部使用)时要小心。

  • 此外,可以通过从“enum”切换到“enum class”来解决此问题。 (2认同)