Forward声明一个继承自不同命名空间中的类的子类

时间:2011-02-19 00:20:42

标签: c++

我不明白为什么无法编译:

#include <SomeType.h> // has a namespace called SomeNamespace

class MyApplication;

int main(...)
{
...
MyApplication application;
...
}

class MyApplication : public SomeNamespace::SomeType {
...
};

目前我从g ++(Ubuntu 4.4.3-4ubuntu5)获得此错误4.4.3

../fix-protocol/main.cpp:44: error: aggregate ‘MyApplication application’ has incomplete type and cannot be defined

5 个答案:

答案 0 :(得分:4)

main中,您实例化了MyApplication类型的对象,该对象仍然是不完整的类型;你不能这样做,因为编译器对还没有任何知识(它需要知道它有多大,如果它有任何构造函数,......)。

要解决您的问题,您必须在实例化该类型的对象之前定义 MyApplication 。通常,您将类定义放在一个带有名称的单独标题中,在任何需要它的文件中都是#include d。

相反,前向声明通常用于打破循环依赖关系和其他类型的场景;他们所说的只是“有一个类似的类”,但它们创建了一个不完整的类型,因此它们只能用于声明其类型的变量,而不是 define 它们。

答案 1 :(得分:3)

在实例化对象之前,必须完全定义

类。 MyApplication application;,您正在尝试实例化一个对象application,但编译器不知道MyApplication的构成是什么,因为它是向前声明的。因此,将定义放在main()之前并删除前向声明。

class MyApplication : public SomeNamespace::SomeType {
    ...
};

int main()
{
    MyApplication application;
}

答案 2 :(得分:3)

您需要在任何实例化之前放置MyApplication的定义。在上面的代码中,编译器不知道要为application变量分配多少堆栈空间,因为它还没有看到MyApplication的定义。

答案 3 :(得分:1)

问题在于C ++的编译器是单通道的,这意味着在程序中的任何一点它都需要能够在不查看文件其余部分的情况下进行操作。在您的情况下,问题是在main函数中,当您编写

MyApplication application;

到目前为止,编译器只看到了类的前向声明(上面的class MyApplication;行)。虽然您稍后会为该类提供定义,但编译器还没有看到它,因此它认为您正在尝试实例化一个尚未定义的类。

要解决此问题,请在MyApplication上方的文件中向上移动main的定义,或在main的定义之后在文件中稍后移动MyApplication。 / p>

顺便说一下,这与继承无关 - 这只是定义类的问题。

答案 4 :(得分:0)

我认为你错过了类型的前向声明这一点。 This answer解释得非常好,并且使用尚未声明的前向声明类型作为基类是不可能的。