结合QT代码学习PIMPL设计模式以及实现方法

 pimpl即 pointer to  implementation,是“指向实现的指针”缩写,这一设计模式主要是用于避免在头文件中暴露私有细节,降低编译依赖,促进API接口和实现的完全分离。

接下来将通过例子来解释该模式的实现方法:

(1)CIMPL.h文件

#include <iostream>
#include "cimpl.h"

using namespace std;

void CIMPL::doSomethingReal()
{
    cout<<"C call CIMPL do something"<<endl;
}
(2)CIMPL.cpp文件
#ifndef CIMPL_H
#define CIMPL_H


class CIMPL//该类写具体的实现方法,等着被调用
{
public:
    void doSomethingReal();
};

#endif // CIMPL_H

(3)C.h文件

#ifndef C_H
#define C_H

class CIMPL;

class C
{
public:
    C();
    ~C();
    void doSomething();
private:
    CIMPL * cImpl;//含有指向CIMPL类的对象指针
};

#endif // C_H

(4)C.cpp文件

#include "c.h"
#include "cimpl.h"

C::C():
    cImpl(new CIMPL)//冒泡赋值法,等价于cImpl=new CIMPL();
                     //此时就会给类C中的成员指针绑定上一个实例对象
{

}

C::~C(){
    delete cImpl;//在C++中new 与delete是一一对应的
                  //在JAVA中则不需要自己写delete,有
                   //自动回收机制
}

void C::doSomething(){
    cImpl->doSomethingReal();//通过指针来调用
}

(5)main.cpp文件

#include <iostream>
#include "c.h"
using namespace std;

int main()
{
    C c;
    c.doSomething();/*C间接调用CIMPL类中的方法,
                      对于用户而言,即使之后CIMPL类
                      中的函数发生变化,此处的调用也不会
                       发生变化*/


    return 0;
}

 在所给的代码中,有一个类CImplement,其中定义了方法dosomethingreal();类同时类C有CImplement类的指针,在主函数中只用实例一个C类对象,此时调用类C的构造函数,而在类C的构造函数中又将CIMPL类指针与CIMPL类对象绑定起来,那么就可以通过该指针调用CIMPL类中的方法dosomethingreal,再将该方法包装为dosomething即可,这样即使以后CImplement中的方法发生了变化,在主函数中也不用改变具体的代码,比较简洁方便。

在QT中的很多源码里面,也是采用了这种编码风格。打开QT,创建一个工程,就会生成一端代码,这段代码的功能是显示一个窗口,仔细分析,其实自动生成的这段代码也是采用了PIMPL思想。

(1)mainwindown.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow//公有继承,Qmainwindown相当于具体的实现类,这里采用继承是出于安全性考虑,为用户封装了类名
{
    Q_OBJECT//引入信号与槽机制

public:
    explicit MainWindow(QWidget *parent = 0);//可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。
                                            //声明为explicit的构造函数不能在隐式转换中使用。
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

(2)main.cpp文件

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

(3)mainwindown.cpp文件

 

    

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),//Qmainwindown相当于之前的Cimlent类
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值