forward声明生成不兼容的类型错误

时间:2010-09-29 15:56:29

标签: c++

我一直在阅读有关前瞻性声明的一些内容,包括在本论坛中。他们都说它可以使我们免于包含头文件,但是下面的代码会产生错误:

#ifndef CLASSA_H_
#define CLASSA_H_

class B;

class A {

public:
    A();
    ~A();
    int getCount();
private:
    static int _count;
    int _num;
    B _b1;   //ERROR

};

编译器说: A.h:23: error: field ‘_b1’ has incomplete type

我注意到如果我_b1类型为B*,问题就解决了。

前向声明只适用于指针类型吗?
如果我希望A保留B对象,我必须#inlcude "B.h"

谢谢!

4 个答案:

答案 0 :(得分:10)

编译器必须知道类B的确切定义,以确定至少为类A提供的大小。如果你使用指针,它就知道它的大小。

请注意,循环依赖项是不可能的。如果你想要

class A { B b; };
class B { A a; };

然后A和B必须具有无限大小...

答案 1 :(得分:6)

您可以使用 前向声明类型

  1. 使用指针和对它的引用作为数据成员
  2. 使用它作为参数(甚至采用每个副本)或返回类型(甚至每个副本返回)用于函数声明
  3. 您需要 类型的完整定义 才能

    1. 将其用作班级数据成员
    2. 在函数 definitions 中使用它。
    3. 如果您还记得前向声明实际上是错误的声明there is no other way of declaring a class type,那么类类型的任何声明都是前向声明),并且,无论何时在class / struct / union加上标识符后打开大括号,您都定义类,所有您需要记住的是你:

      • 需要一个完整的定义才能在定义中使用类型本身
      • 在声明
      • 中仅使用声明来使用类型本身
      • 当您仅使用指针和引用时,只使用声明,并且不尝试访问成员或嵌套类型(前面有.->::的任何内容)

答案 2 :(得分:0)

是的,你必须

#include "B.h"

如果你想在你的A班中加入B.

答案 3 :(得分:0)

是的,只有在使用指向前向声明类型的指针和引用时,前向声明才有效。如果按值使用对象,则需要包含完整的头文件。