在C ++中没有定义的类声明

时间:2012-03-17 09:58:23

标签: c++ qt

我对C ++没有多少经验,我对Qt文档中的以下几行有疑问:http://qt-project.org/doc/qt-4.8/mainwindows-application-mainwindow-h.html(顶部评论后的第4-6行)

 class QAction;
 class QMenu;
 class QPlainTextEdit;

由于QAction,QMenu和QPlainTextEdit是Qt的库类(点击它们导致他们的文档页面),不应该使用'#include'包含它们吗?用关键字“class”声明它们的目的是什么?据我所知,编译器会将它视为一个全新的类,与库类QAction无关。

但是,'mainwindow.cpp'文件(http://qt-project.org/doc/qt-4.8/mainwindows-application-mainwindow-cpp.html)不包含任何类QAction的定义,尽管它的对象正在代码中使用。

这里发生了什么?

编辑:问题的进一步说明

查看MainWindow类(http://qt-project.org/doc/qt-4.8/mainwindows-application-mainwindow-cpp.html)的createActions方法。这里正在创建类QAction的对象,但我无处可找到QAction类的定义。

4 个答案:

答案 0 :(得分:11)

声明一个类,而不是定义,这足以让编译器意识到某个名称引用一个类型的事实,并且允许你在某些设置中使用该类型。具体来说,声明但尚未定义的类型是不完整类型,您可以通过多种方式使用不完整类型:

  • 在函数声明中,函数的返回类型和参数类型可能不完整(但当然不在函数的定义中)。*

  • 如果T是不完整的类型,那么T*T&以及它们的CV限定版本都是完整类型。

所以你可以写下以下内容:

class Foo;  // we only need to know that `Foo` names a type.

struct Bar { Foo * p; };   // complete definition of `Bar`.

Foo mangle(Foo x, Foo y);  // function declaration

您可以根据需要随时声明一个类或任何类型的类。唯一必须是唯一的是定义(“One Definition Rule”)。

*)有一个例外:void始终不完整,并且您可以通过不返回任何内容来返回void类型。

答案 1 :(得分:4)

这些被称为“forward declarations”的类。它用于使编译器知道那些符号引用了类,这些类将在之后定义。这些可以在头文件中使用,以声明符号是一个类,避免包含其标题,在某些情况下可能需要(例如圆形包含)。

无论如何,您无法始终使用前向声明,因为编译器可能需要知道如何定义类。在其他情况下,编译器只需知道它实际上是一个类的事实。

编辑:要回答您添加的以下问题,请查看您可以在* qt_install_dir * / include / QtGui中找到的QtGui文件。在我的Qt 4.8安装中,我看到里面:

#include "qaction.h"

然后查看qaction.h:你会看到QAction类的完整定义。包含头文件QtGui就在你的mainwindow.cpp的开头,这使得QAction成为一个完整的类型。

答案 2 :(得分:0)

类的类型完全取决于其完全限定名称(不确定是官方术语,但无论如何),包括其名称空间和名称。它是来自头文件还是简单地声明 in-situ 并不重要。

实际上,包含头文件基本上只是将该标题的文本插入到包含出现的源代码点。效果与使用您喜欢的文本编辑器将#include替换为头文件的内容相同。无论哪种方式,编译器本身只能看到一个令牌流。

使用前向声明的主要目的是通过减少它必须解析的文本量以及它在RAM中构建的符号表的大小来加速编译器。我发现这种做法在我自己的工作中很大程度上是不必要的,但是非常大的项目可能仍然有益。

答案 3 :(得分:-2)

几天前,我正在研究这个例子。所以这就是我认为你需要这些的结论:

我猜测如果你查看.pro文件,你会看到一行如下:

QT += core
QT += gui

所以问题是你告诉Qt翻译器和编译器你正在使用QtGui和QtCore模块,并且在那些模块中你已经定义了QAction等。因此,作为“hack”(因为他们的IDE在编译过程的后期阶段无法自动检测到它),所以您预先声明了类,以避免在编译阶段出现任何错误。最后,Qt插入模块,一切正常。

这让我第一次做到这一点时头疼,但这是我能得到的唯一合乎逻辑的解释。

如果您没有预先声明该类,您将收到一条错误消息,指出它无法找到对该类的任何引用等。

编辑: 根据您最近的更新,我建议您访问YouTube并在昵称下搜索用户:voidrealms。他有很好的C ++ Qt视频教程和解释,在那里他还展示了QMenu,QAction等。他有关于Qt C ++编程的150多个视频,涵盖了从基本的Hello World到网络编程的所有内容,甚至还包括......检查他,他还有其他教程