【问题标题】:Class name does not name a type in C++类名不命名 C++ 中的类型
【发布时间】:2011-04-06 05:12:43
【问题描述】:

我刚开始用 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 类,然后我得到了错误信息:

A.h:9:错误:“B”没有命名类型

我该如何解决这个问题?

【问题讨论】:

  • @Georg 为什么你把所有东西都放在一个代码段中?它们是不同的文件。
  • @Amir: 在我点击 edit 之前它看起来已经坏了,我心不在焉:)
  • 您可以通过单击答案旁边的勾号来接受您认为最有用的答案之一。这将有助于其他遇到类似问题的人。
  • @Naveen 有一个最短时间,所以还没有:P
  • 我把所有东西都放在一个代码段中,因为一开始根本没有任何代码段。

标签: c++


【解决方案1】:

在“A.h”中包含“B.h”。这会在编译“A”时为编译器带来“B”的声明。

第一个项目符号适用于 OP。

$3.4.1/7 -

"在定义中使用的名称 成员函数之外的类 X 主体或嵌套类定义27) 应在其中之一声明 以下方式:

——在使用之前 X 类或成为基类的成员 X (10.2),

——如果 X 是嵌套的 Y 类(9.7)类,在 X 在 Y 中的定义,或应为 Y 基类的成员(这个 查找依次适用于 Y 封闭类,从 最里面的封闭类),28) 或

——如果 X 是本地类 (9.8) 或 本地类的嵌套类,之前 块中类 X 的定义 附上 X 类的定义, 或

——如果 X 是命名空间 N 的成员, 或者是一个类的嵌套类 是 N 的成员,或者是本地类 或本地类中的嵌套类 作为 N 的成员的函数, 在定义类 X 之前 命名空间 N 或在 N 的封闭之一中 命名空间。”

【讨论】:

    【解决方案2】:

    您必须首先包含来自A.hB.hB b;在您包含 B.h 之前没有任何意义。

    【讨论】:

      【解决方案3】:

      问题是您需要在您的A.h 文件中包含B.h。问题是在A的定义中,编译器仍然不知道B是什么。您应该包括您正在使用的所有类型的所有定义。

      【讨论】:

        【解决方案4】:

        当你在 A.h 中定义类 A 时,你明确地说该类有一个成员 B。

        您必须在“A.h”中包含“B.h”

        【讨论】:

          【解决方案5】:

          你不是错过了 A.h 中的#include "B.h" 吗?

          【讨论】:

            【解决方案6】:

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

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

              class B; // forward declaration        
              class A {
              public:
                  A(int id);
              private:
                  int _id;
                  B & _b;
              };
              

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

            我希望这会有所帮助。

            【讨论】:

            • 这是一个很好的答案,但我建议使用指针而不是引用。引用必须从声明的那一刻起就被初始化,认为不可能将引用存储为类成员而不会出错。
            【解决方案7】:
            error 'Class' does not name a type
            

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

            我对解决方案的搜索把我带到了这里,所以我猜其他人也可能发生同样的情况。

            【讨论】:

            • 天哪,谢谢你!我正在阅读几十个链接来解决我的问题。 #facepalm!
            【解决方案8】:

            今天我的问题的解决方案与这里的其他答案略有不同。

            就我而言,问题是由于包含链中的一个头文件末尾缺少右括号 (}) 引起的。

            基本上,发生的事情是A 包括B。因为B 在文件中的某处缺少},所以B 中的定义在A 中没有正确找到。

            起初我以为我有循环依赖并添加了前向声明B。但随后它开始抱怨B 中的某些内容是不完整的类型。这就是我想到仔细检查文件是否存在语法错误的方式。

            【讨论】:

              【解决方案9】:

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

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

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

              这引发了相同的编译器错误消息,提及 Class A does not name a type。在我的情况下没有循环依赖。

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

              【讨论】:

              • 另外,这可以通过从enum切换到enum class来解决。
              • 名称与函数的冲突也会发生同样的情况!我试图使用struct Rectangle,但在Windowswingdi.h 上定义了一个函数 Rectangle。我认为在这种情况下,唯一的选择是重命名结构,或者在任何地方将其称为struct Rectangle
              【解决方案10】:

              这实际上发生在我身上,因为我错误地将源文件命名为“something.c” 而不是“something.cpp”。 我希望这对有同样错误的人有所帮助。

              【讨论】:

                【解决方案11】:

                尝试将所有包含移到命名空间之外。

                //Error
                namespace U2 {
                
                #include <Head.h>
                #include <LifeDiode.h>
                
                }
                

                //解决办法

                #include <Head.h>
                #include <LifeDiode.h>
                
                namespace U2 {
                
                }
                

                【讨论】:

                  猜你喜欢
                  • 2022-01-12
                  • 2010-09-17
                  • 2013-03-25
                  • 2020-09-19
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-03-14
                  相关资源
                  最近更新 更多