【转】一个非常常见但容易被忽略的c++问题——用IPML模式可以解决

简介:

   pimpl (the pointer-to-implementation idiom)手法在 C++ 里已是“高手”们广泛运用的成熟方法之一,它的优点很多,诸如降低编译依赖、提高重编译速度之类的工具性优势自不待赘言,而其对“保持接口稳定性”的优点更值得称道。

      It makes it possible to avoid other classes to know internal data structures and other information of the class. It also simplifies some#includepreprocessor instructions.避免别的class知道其内部的数据结构。还可以简化预编译指令。

      pImpl方法是微软的Herb Sutter提出来的,该方法是为了尽量减小接口和实现之间的耦合,以避免接口改动对程序重新编译等带来的影响。简单来说,如果你的大型程序因为复杂的头文件包含关系,使得你对某头文件的某小改动可能引起的巨大编译时间成本望而生畏,那么你需要用pImpl方法来改善这种处境。

    下面看两个代码示例。

    1、

    #include "classA.h"

    class B

    {

      …

      classA a;

    };

 

    2、

    class classA;

    class B

    {

      …

      classA* pa;

    };

 

    这两个代码都是对classB的声明,可能会在我们工程的classB.h文件中。它们唯一的不同是1直接引用了classA.h头文件,并声明了classA类型的变量a;而2是通过"class classA;"这句进行classA的声明,然后声明了一个classA类型的指针变量pa,很明显,在2的classB.cpp文件中,需要添加#include "classA.h"。

    我们来看看1会发生什么事情。如果你的classB.h文件又被其他头文件classC.h引用,而classC.h又被classD.h文件引用,当你的工程足够复杂,你的头文件之间的引用可能会非常杂乱,问题会随之出现,比如重复引用(幸好我们有#ifdef和#pragma once等方法帮我们解决问题),比如交叉引用(a引用b,b引用a,头疼),还有可能引用一些本不需要的头文件。如果你觉得这些问题都可以忽略,那么当你需要改动classA的声明时,不能忽略的问题来了,所有引用该文件的cpp文件都需要重新编译,对于大型工程,这个编译时间成本有时是不能忽略的。你总不能每改动一次classA,就把几乎大部分代码重新编译一次吧,对于开发和调试来说,这几乎不能忍受。

    在1中,classA a语句必须要求引用classA的声明,以便给a变量分配空间;而2中的classA* pa语句则不需要知道classA的具体声明,因为任何指针所占用的空间都是一定的。这样,classB与classA之间就没有了耦合,classA的任何改动,对于classB来说都没有影响,除非classB修改了对classA调用的代码。在这里,指针起到了解耦合的作用。

    pImpl方法是应该被提倡应用的,如果运用的恰当,对于工程开发、维护和编译都能起到正面作用,对于这种编码习惯,是需要我们在平时就注意培养的。

 本文转自编程小翁博客园博客,原文链接:http://www.cnblogs.com/wengzilin/p/3554624.html,如需转载请自行联系原作者

相关文章
|
2月前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
54 0
|
2月前
|
设计模式 编译器 API
【C/C++ Pimpl模式】隐藏实现细节的高效方式 (Pimpl Idiom: An Efficient Way to Hide Implementation Details)
【C/C++ Pimpl模式】隐藏实现细节的高效方式 (Pimpl Idiom: An Efficient Way to Hide Implementation Details)
73 1
|
4月前
|
数据采集 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置软件触发模式(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置软件触发模式(C++)
34 0
|
2月前
|
消息中间件 负载均衡 监控
【ZMQ PUB模式指南】深入探究ZeroMQ的PUB-SUB模式:C++编程实践、底层原理与最佳实践
【ZMQ PUB模式指南】深入探究ZeroMQ的PUB-SUB模式:C++编程实践、底层原理与最佳实践
252 1
|
2月前
|
设计模式 中间件 程序员
【C/C++ 奇异递归模板模式 】C++中CRTP模式(Curiously Recurring Template Pattern)的艺术和科学
【C/C++ 奇异递归模板模式 】C++中CRTP模式(Curiously Recurring Template Pattern)的艺术和科学
22 3
|
2月前
|
算法 编译器 程序员
深入理解C++编译模式:了解Debug和Release的区别
深入理解C++编译模式:了解Debug和Release的区别
67 2
|
2月前
|
消息中间件 存储 监控
【ZeroMQ的SUB视角】深入探讨订阅者模式、C++编程实践与底层机制
【ZeroMQ的SUB视角】深入探讨订阅者模式、C++编程实践与底层机制
142 1
|
2月前
|
设计模式 算法 编译器
【C/C++ PIMPL模式 】 深入探索C++中的PIMPL模式
【C/C++ PIMPL模式 】 深入探索C++中的PIMPL模式
53 0
|
2月前
|
设计模式 负载均衡 算法
C/C++发布-订阅者模式世界:揭秘高效编程的秘诀
C/C++发布-订阅者模式世界:揭秘高效编程的秘诀
81 1
|
7月前
|
设计模式 网络协议 Java
Reactor 模式网络服务器【I/O多路复用】(C++实现)
Reactor 模式网络服务器【I/O多路复用】(C++实现)
263 0