类名没有命名 C 中的类型

新手上路,请多包涵

我刚开始用 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 许可协议

阅读 566
2 个回答

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

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

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

我希望这有帮助。

原文由 Björn Pollex 发布,翻译遵循 CC BY-SA 3.0 许可协议

不是答案,但对我来说,问题是我忘记在潜在类型之前添加 std:: 以正确使用它。

原文由 Caio V. 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题