Qt 类的前置声明和头文件包含

1. 在头文件中引入另一个类经常有两种写法

1)前置声明 2)头文件包含

cpp 复制代码
#ifndef FRMCOUPLE2_H
#define FRMCOUPLE2_H

#include <QWidget>    //头文件包含

namespace Ui {
class frmcouple2;
}

//前置声明:QPushButton frmchkeyboard
class QPushButton;
class frmchkeyboard;
class frmcouple2 : public QWidget
{
    Q_OBJECT

public:
    explicit frmcouple2(QWidget *parent = nullptr);
    ~frmcouple2();

private:
    Ui::frmcouple2 *ui;
    QPushButton *btn_close_extend = nullptr ;
    QPushButton *btn_tx_ms = nullptr;
    frmchkeyboard *m_pFrmChKeyBoard = nullptr;
};

#endif // FRMCOUPLE2_H

2. 区别

前置声明 :前置声明类会告诉编译器,这些类已经存在了,并且不需要知道这些类的完整定义;可以对其使用指针或者引用,不能定义该类的实例化对象;

例如:

当我们用 class QNetworkAccessManager;时,我们可以对其使用指针或者引用:
QNetworkAccessManager *m_manager;
我们不能QNetworkAccessManager m_manager;否则如下:

头文件包含 :则是将整个该头文件与使用到的地方关联起来,所以你可以知道该类的具体信息。可以对其使用指针或者引用,也可以定义该类的实例化对象;

  1. 前置声明的优势

1)避免了头文件被其他文件多次包含,尤其是在头文件中包含头文件时,容易造成重复包含和产生包含顺序问题(最坏情况:当类A和类B互相调用时候产生死循环),并且增大了文件的体积;

2)可以去除编译依赖,减少编译消耗的时间。

例如:如果使用#include "Name.h" 一旦Name的定义需要修改,Name.h也就会重新编译,导致所有用到Name.h的文件也需要重新编译,这样就造成了编译依赖,增加了编译的时间,在大型项目中,如果很多这样的地方的话,甚至可能极度增加编译时间。

4. 使用前置声明的时机

当你在头文件中只用到一些类的指针(而非实现),那么就可以不包含这些类的头文件,而去使用类的前置声明。

5. 两个类相互包含实例

cpp 复制代码
// 错误案例

// a.h
class A { }

// b.h
class B { }

// 如果想在类A中使用类B,在类B中使用类A,应该怎么办

// a.h
#include "b.h"
class A
{
    B *b
}

// b.h
#include "a.h"
class B 
{
    A *a
}

// 上面的方法一定是编译失败的 ...
cpp 复制代码
// 正确方法
// a.h
#include "a.h"
#include "b.h"
class A 
{
    B *b = new B();
    b.a = this;
    void hello() {};
}

// b.h
class A;
class B
{
    A *a;
}

// b.cpp
#include "b.h"
#include "a.h" // 只能在 b.cpp 里面 include a.h
B::B()
{
    a.hello();
}