C++ 惯用法之 PIMPL
2024-02-01 12:47:26 软件 179观看
摘要一、背景1.概述PIMPL 是 C++ 中的一个编程技巧,意思为指向实现的指针。具体操作是把类的实现细节放到一个单独的类中,并用一个指针进行访问。2.二进制兼容性(1) 概述二进制兼容是指当库文件升级后所有使用该库的应用程

一、背景

1.概述

PIMPL 是 C++ 中的一个编程技巧,意思为指向实现的指针。具体操作是把类的实现细节放到一个单独的类中,并用一个指针进行访问。7N828资讯网——每日最新资讯28at.com

7N828资讯网——每日最新资讯28at.com

2.二进制兼容性

(1) 概述

二进制兼容是指当库文件升级后所有使用该库的应用程序不必重新编译,其本质就是类的内存布局不变。使用 pimpl 方法设计类可以实现二进制兼容的目的。7N828资讯网——每日最新资讯28at.com

(2) 类成员更改后的内存布局

原始类定义:7N828资讯网——每日最新资讯28at.com

class demoClass{private:  int a;  int b;};

内存布局如下:7N828资讯网——每日最新资讯28at.com

7N828资讯网——每日最新资讯28at.com

类更改后的定义:7N828资讯网——每日最新资讯28at.com

class demoClass{private:  char c;  int a;  int b;};

内存布局如下:7N828资讯网——每日最新资讯28at.com

7N828资讯网——每日最新资讯28at.com

(3) pimpl 下类的内存布局

class demoClass{private:  class demoClassImpl;  demoClassImpl* impl;};class demoClass::demoClassImpl{public:  int a;  int b;};

内存布局如下:7N828资讯网——每日最新资讯28at.com

7N828资讯网——每日最新资讯28at.com

如上图所示,无论类的实现类的数据成员如何变化,类的布局始终不变。7N828资讯网——每日最新资讯28at.com

二、pimpl 应用

1.功能实现细节隐藏

(1) 概述

作为接口的提供者,我们希望接口的使用者不必知道接口实现的更多细节,因为根据类的私有数据成员和方法一般就可以猜测出接口的设计方式。7N828资讯网——每日最新资讯28at.com

(2) 隐藏实现细节

通过 pimp 方法设计类可以实现隐藏类的私有成员和方法的目的,仅对外暴露公有的接口。7N828资讯网——每日最新资讯28at.com

class demoClass{public:  void func();//对外接口private:  class demoClassImpl;  demoClassImpl* impl;};class demoClass::demoClassImpl{private:  int a;  int b;    void func1();  void func2();public:  void func();};void demoClass::func(){  impl->func();}

2.降低编译依赖

(1) 概述

在一个常用的头文件中如果包含了太多其他不必要的头文件会严重降低编译效率。7N828资讯网——每日最新资讯28at.com

(2) 值类型的成员必须引用其头文件

值类型的成员因为要分配内存大小必须知道其确定的定义,需要包含其头文件7N828资讯网——每日最新资讯28at.com

#include "A.h"class demoClass{  A a;};

如果仅有类的申明则会出错:7N828资讯网——每日最新资讯28at.com

class A;class demoClass{  A a;};

7N828资讯网——每日最新资讯28at.com

(3) 指针或者引用类型,仅需要类的申明

class A;class demoClass{  A  func(A a);};

(4) 使用 pimpl 降低编译依赖

一般库文件使用者仅需要包含当前库对应的头文件即可,不应该再包含其他的头文件。假设库的头文件定义如下:7N828资讯网——每日最新资讯28at.com

#include "A.h"class demoClass{private:  A a;public:  void func();};

此时,若 A 为另外一个公共库,则库的使用者需要在项目中配置 A.h 的路径;若 A 为自定义类,则库的提供者还需要额外提供 A.h 文件。7N828资讯网——每日最新资讯28at.com

使用 pimpl 方法改进则可以减少编译依赖,仅在类的实现文件中包含头文件即可:7N828资讯网——每日最新资讯28at.com

// demoClass.hclass demoClass{public:  void func();//对外接口private:  class demoClassImpl;  demoClassImpl* impl;};// demoClass.cpp#include "A.h"class demoClass::demoClassImpl{private:  A a;public:  void func();};

2.动态配置功能的实现方法

(1) 概述

使用 pimpl 的方式把类的功能实现用另外一个独立的类来完成,可以在需要的时候动态的配置类的实现方法,而保持类的接口不变。7N828资讯网——每日最新资讯28at.com

(2) 代码示例

公共接口类:7N828资讯网——每日最新资讯28at.com

class demoClassImpl;class demoClass{public:    void func();//对外接口public:    demoClassImpl* impl;};void demoClass::func(){    impl->func();}

功能实现抽象类:7N828资讯网——每日最新资讯28at.com

class demoClassImpl{public:    virtual void func() = 0;};

功能实现派生类:7N828资讯网——每日最新资讯28at.com

class demoClassImpl1 : public demoClassImpl{public:    void func() { cout << "实现方式1" << endl; }};class demoClassImpl2 : public demoClassImpl{public:    void func() { cout << "实现方式2" << endl; }};

功能实现方式的动态配置:7N828资讯网——每日最新资讯28at.com

demoClass* demo = new demoClass;demoClassImpl1* impl1 = new demoClassImpl1;demo->impl = impl1;demo->func();demoClassImpl2* impl2 = new demoClassImpl2;demo->impl = impl2;demo->func();

7N828资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-70407-0.htmlC++ 惯用法之 PIMPL

声明:本网页内容旨在传播知识,不代表本站观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。

显示全文

上一篇:十个React状态管理库推荐:打造高效、可维护的前端应用

下一篇:探秘C++的移动语义:释放力量,提升性能

最新热点