Qt源码解析之-从PIMPL机制到d指针

本文介绍了PIMPL(Private Implementation)机制,旨在减少头文件依赖,提高编译速度和解耦。通过一个产品类的例子展示了PIMPL的使用,并分析了Qt框架中如何运用d指针实现PIMPL,详细解析了QThread类的构造函数、Q_D宏、d_func()方法等,阐述了Qt中d指针的由来和作用。

  一、PIMPL机制
  
  PIMPL ,即Private Implementation,作用是,实现 私有化,力图使得头文件对改变不透明,以达到解耦的目的
  
  pimpl 用法背后的思想是把客户与所有关于类的私有部分的知识隔离开。由于客户是依赖于类的头文件的,头文件中的任何变化都会影响客户,即使仅是对私有节或保护节的修改。pimpl用法隐藏了这些细节,方法是将私有数据和函数放入一个单独的类中,并保存在一个实现文件中,然后在头文件中对这个类进行前向声明并保存一个指向该实现类的指针。类的构造函数分配这个pimpl类,而析构函数则释放它。这样可以消除头文件与实现细节的相关性
  
  该句出自 超越 C++ 标准库--boost程序库 导论
  
  该文的代码说明均忽略一些简单必须的代码,以保证示例的简洁,比如防止头文件重复包含等
  
  (1)实例说明
  
  假设现在有一个需求,你需要写一个类,来完成产品的信息保存和获取,这个需求看起来非常的简单,我们只需要一分钟就能写好
  
  Product.h
  
  class Product
  
  {
  
  public:
  
  string getName() const;
  
  void setName(const string& name);
  
  float getPrice() const;
  
  void setPrice(float price);
  
  private:
  
  string name;
  
  float price;
  
  };
  
  Product.cpp
  
  string Product::getName() const
  
  {
  
  return this->name;
  
  }
  
  void Product::setName(const string &name)
  
  {
  
  this->name = name;
  
  }
  
  float Product::getPrice() const
  
  {
  
  return this->price;
  
  }
  
  void Product::setPrice(float price)
  
  {
  
  this->price = price;
  
  }
  
  当然,你可能会说,这个简单的代码根本不需要cpp,但是我们这里只是举个例子,实际的情况肯定比这复杂的多的多。
  
  言归正传,我们完成了我们的模块,并交付出去提供给他人调用,结果第二天,有了新的需求,你需要新增一个成员变量,用作其中某个业务逻辑的数据存储,所以你不得不在头文件中的class内新增了一个成员属性,并在cpp中修改逻辑,辛运的是对外开放的接口并没有任何变动,调用你的模块的地方不需要修改代码。完成之后,交付使用。
  
  然后这时候问题来了,调用此模块的人向你抱怨,替换了你的模块之后,明明自己没有修改任何东西,但是整个工程重新编译了整整半个多小时(可能有些夸张)。因为整个工程代码量巨大,很多地方都使用了你的模块,包含了你的头文件,导致这些包含你的头文件的地方虽然没有变动,但是都重新编译了。
  
  利用PIMPL机制,将私有成员隐藏起来,使得只有接口不变,那么头文件就不会改变,已达到解耦的目的。从上面例子也可以看出,PIMPL机制的好处之一就是避免头文件依赖,提高编译速度。
  
  那利用PIMPL机制,上面的问题如何解决呢?
  
  可以看出来,Product 类除了必要的接口函数外,就只有一个ProductData指针了,而ProductData又是使用的前置声明,在cpp中实现,这样,只要接口不变,那么内部私有成员或者逻辑改变,并不会影响client
  
  上面的代码只是最简单的实现,其中还存在很多问题,而实际的项目中可能要复杂的多。尽管如此,我们也能看出PIMPL机制的优点:
  
  降低耦合度;
  
  隐藏模块信息;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值