前瞻性的阶级宣言

时间:2010-09-06 09:44:02

标签: c++

在A.h我有以下课程

class A
{
  int a;
  char name[100];
}

B.h有以下代码

class A;
Class B
{
  public:
   int c;
   float d;
   getObjectDetails(A *);
};

我将其编译为g++ A.h B.h B.cpp -o out。但它给出了编译错误,说A类不完整。有人可以帮我理解吗?

另外,如果我在B.h中包含头文件A.h,一切都很顺利。在这种情况下,我不需要在B类定义之前声明A类,我认为,我可以直接创建和使用A类实例。有人可以在这一点上澄清我吗?

在编译时和运行时的步骤“A类”声明中会发生什么?

6 个答案:

答案 0 :(得分:1)

  

您只能使用转发声明   用指针和引用(因为   这些都是固定的,独立的   他们引用的对象的大小   至)。如果你使用特定的类   值,编译器需要它的全部   定义(以了解其确切的   大小),因此前向声明不是   够了。

     

您只能使用转发声明   用于类型识别,例如何时   你在a中使用声明的类型   函数/方法指针参数   原型。如果你要宣布   成员变量(即std :: string   _name;)编译器需要比前向声明多一点   可以给它。例如,如果有人   做一个sizeof(学生)编译器   必须有权访问整个   宣布找出尺寸。

来自Péter Török主题的this回答。

答案 1 :(得分:1)

如果你

,它应该编译好

1)在A类声明的末尾添加一个分号。

2)在B类声明中将“C”改为“c”。

3)向getObjectDetails()

添加一个返回类型

答案 2 :(得分:0)

问题肯定在B.cpp,因为B.h很好。如果您尝试对A*收到的getObjectDetails()执行任何操作(例如调用其上的方法),编译器将无法理解它。

要解决这个问题,请尝试将A.h包含在B.cpp中(B.h确实不需要它。)

答案 3 :(得分:0)

你可能在#include "A.h"中没有B.cpp,然后使用A这样就需要定义A,而不仅仅是声明。如果没有这个定义,那么传递给A*的{​​{1}}唯一可以做的就是将其存储在getObjectDetailsA*变量中,或者将其传递给某些变量void*以外的其他代码。

答案 4 :(得分:0)

你应该从B.h. #include A.h.你所做的事情被称为前向声明,只有当A.h包含大量代码或包含其他文件时才推荐使用。然后,“A级;”事情可以让你的编译器知道A是一个类的快速方法,因此接受指针和对A对象的引用,而无需解析来自A.h.的所有额外代码。 你的Ah不足以证明这样的黑客行为。最好直接使用关于A的信息来源,这是啊,而不是传播有关A的信息(可能有一天会停止在整个B.我是积极地不喜欢这个前瞻宣言黑客,并建议创建一个包含“A类”的专用前向声明标题。和A.h增长的任何其他类都包含,因此像B这样的用法可以包含它们,如果它们不需要完整的声明。这是由标准库完成的,它向前声明了较重的有用的类,变量和常量。

然后,你的B.cpp应该#include B.h.您的命令行应该只是:

g++ B.cpp -o out

(无需提及A.h或B.h,因为它们将被包括在内(分别间接和直接)来自B.cpp。

答案 5 :(得分:0)

此代码

class A;
class B
{
public:
    int c;
    float d;
    void getObjectDetails(A *);
};

使用VC9(VS 2008)编译好 ,我相信这是正确的。

如果你的代码没有编译,那么与上面的代码有很大不同。找到它(我们无法找到它)的唯一方法是获取原始代码的(副本),并开始逐步删除内容,直到错误消失为止。
要么您了解问题是什么,要么最终得到< 20行自包含示例代码重现错误 - 这是一个完美的复制品,可以回到这里询问。