欢迎光临散文网 会员登陆 & 注册

【C/C++程序设计技巧】Pimpl机制

2021-11-02 11:28 作者:四川学到牛科技  | 我要投稿

作者:学到牛牛任金城,欢迎关注公众号【学到牛牛】。
更多入门到精通课件、资料联系作者君或参看这里:学到牛牛 www.xuedaon.com

我们平时在编写C/C++程序时我们都会在源文件(后缀为.c或.cpp的文件)中包含头文件,当头文件内容发生改变时,包含其的源文件在编译时也需要重新编译,也就是现在假如有如下关系图:

这里的N个cpp文件都包含了A.h,当每次修改A.h内容,再次编译时这里的N个cpp文件无论内容是否改变都将重新编译!这时就好比是牵一发而动全身,会导致编译效率低下;

那么该如何解决呢?也就是如何才能做到既能兼顾头文件内容的可扩展兼容性,又能去掉那些重复无效的编译(编译那些无需再次编译的源文件即内容并未发生改变的源文件)。这就是我们今天的主角——PIMPL机制(一种利用指针实现的数据私有化可扩展兼容机制)。我们先来看一个没有引入PIMPL机制的情况,测试代码如下:



我们再编写一个Makefile文件来模拟IDE的编译过程:



当我们执行make时效果如下:


此时若我们没做任何文件修改若直接再次执行make效果则会是:



当我们将头文件person.h中注释的测试成员取消注释:


后再执行make的效果:


此时我们会发现所有的.cpp源文件又都重新被编译,但他们都未做任何更改,那这些编译目前来说都是无效的没有必要的编译,这里增加的属性就好比是针对于windows环境做出的调整改变,本质对当前环境是没有任何影响的,当前环境下也不需要去关心这个变化,但是它却影响了当前环境下的编译,这样肯定是不太好的,所以我们就可以利用PIMPL机制来改进,即在原类对象中提供一个用于存储数据的私有对象指针,将类对象中原有的私有数据成员放入在源文件在定义的私有对象中还可以定义相关访问接口便于原对象调用,具体简单改进后代码如下:



此时当我们第一次执行make时效果与之前一样会编译所有源文件:



但当我们在私有数据对象中改变时(将现在PrivatePersonData中int m_addTest;注释去除)再make时的效果:



此时我们可以看出与修改后无关联的源代码(man.cpp与xuedaon.cpp)并没有再次重新编译,这样就既能兼顾头文件内容的可扩展兼容性,又能去掉那些重复无效的编译,并且还相当于对外隐藏了Person类中原有的数据成员,防止代码的盗用;在Qt中就是利用在源文件中定义私有对象配合定义Q_DECLARE_PRIVATE(定义获取私有对象的指针的接口函数和声明私有对象)与Q_D宏定义(调用接口获取私有对象的指针)实现的PIPML机制,有兴趣的可以看看下面的源代码:


希望上面的介绍能对大家理解PIMPL机制有所帮助!祝大家在学习的道路上能更上一层楼。







【C/C++程序设计技巧】Pimpl机制的评论 (共 条)

分享到微博请遵守国家法律