Qt包含和预编译标头的最佳实践

Best Practice For Qt Includes And Precompiled Headers?

本文关键字:最佳 包含 编译 Qt      更新时间:2023-10-16

在使用激活了预编译头的现代和最新C++编译器(例如MSVC2015)时,当前关于包含Qt头文件的"最佳实践"是什么?

示例:

#include <QStringList> 
#include <QTreeWidget>
#include <QListWidget>

与。

#include <QtCore>
#include <QtGui>
  • 对于一个新项目,我应该选择什么约定?

  • 两者的优点/缺点是什么?

  • 新项目中更常见的是什么?

据我所知,Qt-includes和预编译头没有特定的限制/推荐/优点/缺点。当包含第三方头文件(Qt或boost或其他)时,同样的规则适用。

一般来说(Qt-includes也是如此,但也适用于任何其他第三方includes,例如STL,甚至在包含自己的代码时),您应该将includes最小化。包含的文件越少,编译速度就越快。包含实际上不需要的文件会使编译速度变慢。此外,如果您包含但未使用的此类头文件被编辑/修改(通常情况下,第三方头文件不应如此),则包括它在内的任何文件都需要重新编译,即使它没有真正使用包含的代码。。。。

因此,一般规则是只包含您真正需要的文件。因此,如果您的文件只需要QStringList,请选择包含<QtCore/QStringList>而不是<QtCore>

如果你关心编译时间,也要确保在必要时只包括头文件(.h)中的文件,如果可以使用正向声明,请使用它,并只包括实现(.cpp)中必要的头文件。当头文件被修改时,这将大大减少项目的编译时间(请阅读此文)。

现在,如果您的项目有许多文件,其中包括一些Qt文件,则可以使用预编译头来优化编译。然后,这些文件将被编译一次,而且只编译一次。然而,由于所有文件最终都将使用相同的预编译头(本身包括许多头文件),因此只有在以下情况下才应该这样做:

  • 预编译的头文件应该主要是第三方头文件,这样它们就不会更改。因为如果发生更改,则所有文件都需要重新编译
  • 编译器必须支持预编译头(否则,编译可能会工作,但也可能会变得更慢,因为每个文件最终都会包括项目的所有预编译的头……所以可能比实际需要的文件更多)

我在所有项目中使用next(用于预编译头):

#pragma once
#ifdef QT_CORE_LIB
# include <QtCore>
#endif
#ifdef QT_CONCURRENT_LIB
# include <QtConcurrent>
#endif
#ifdef QT_GUI_LIB
# include <QtGui>
#endif
#ifdef QT_WIDGETS_LIB
# include <QtWidgets>
#endif
#ifdef QT_MULTIMEDIA_LIB
# include <QtMultimedia>
#endif
#ifdef QT_NETWORK_LIB
# include <QtNetwork>
#endif
#ifdef QT_XML_LIB
# include <QtXml>
#endif
#ifdef QT_QML_LIB
# include <QtQml>
#endif
#ifdef QT_QUICK_LIB
# include <QtQuick>
#endif
#ifdef QT_SQL_LIB
# include <QtSql>
#endif
#ifdef QT_PRINTSUPPORT_LIB
# include <QtPrintSupport>
#endif

只有在连接模块时,它才会包含必要的定义。适用于msvs+qt插件或基于cmake的项目(我使用cotire)。

包含更少的头可以减少编译时间,仅此而已,因此如果您执行

#include <QtCore/QStringList>

编译它比稍微快一点

#include <QtCore>

如果您确信您依赖于QtCore中的所有内容,请将其包含在内,否则,请分别包含每个标头。