![更多课程](/zhuzhan/img/btn-course.png)
![选择中心](/zhuzhan/img/btn-center.png)
![logo](/zhuzhan/img/logo.png)
C/C++培训
达内IT学院
400-111-8989
![](/zhuzhan/images/weixin.jpg)
Pimpl是一种常用的,用来对“类的接口与实现”进行解耦的方法。这个技巧可以避免在头文件中暴露私有细节,因此是促进API接口与实现保持完全分离的重要机制。但是Pimpl并不是严格意义上的设计模式(它是受制于C++特定限制的变通方案),这种惯用法可以看作桥接设计模式的一种特例。
pimpl惯用法的主要作用:对类的接口和实现解耦合。如果不使用pimpl惯用法,代码会像这样:
//C.hpp
#include<X.hpp>
class C
{
public:
void f();
private:
X x; //与X的强耦合
};
像上面这样的代码,C与它的实现就是强耦合的,从语义上说,x成员数据是属于C的实现部分,不应该暴露给用户。从语言的本质上来说,在用户的代码中,每一次使用“new C”和“C c1”这样的语句,都会将X的大小硬编码到编译后的二进制代码段中(如果X有虚函数,则还不止这些),这是因为,对于“new C”这样的语句,其实相当于operator new(sizeof(C) )后面再跟上C的构造函数,而“C c1”则是在当前栈上腾出sizeof(C)大小的空间,然后调用C的构造函数。因此,每次X类作了改动,使用c.hpp的源文件都必须重新编译一次,因为X的大小可能改变了。在一个大型的项目中,这种耦合可能会对build时间产生相当大的影响。
pimpl惯用手法可以将这种耦合消除,使用pimpl惯用手法的代码像这样:
//C.hpp
class X; //用前导声明取代include
class C
{
public:
void f();
private:
X * pImpl; // 声明一个X *的时候,class X不用完全定义
};
在一个既定平台上,任何指针的大小都是相同的。正由于pImpl是个指针,所以这里X的二进制信息(sizeof(C)等)不会被耦合到C的使用接口上去,也就是说,当用户“new C”或“C c1”的时候,编译器生成的代码中不会掺杂X的任何信息,并且当用户使用C的时候,使用的是C的接口,也与X无关,从而X被这个指针彻底的与用户隔绝开来。只有C知道并能够操作pImpl成员指向的X对象。
pimpl惯用法通过将私有数据和函数放入到定义在实现文件中的一个单独类型中,然后在头文件中对这个类型进行前置声明并保存一个指向该类型的指针,隐藏了相关细节内容。类的构造函数分配pimpl类型,而析构函数则释放它。这就消除了实现细节和头文件的相关性。
以上就是关于C++中的pimpl惯用法当你还在担心能否就业时,达内学员提前被企业录取;当你转辗于各大招聘会时,达内学员收到了高薪offer;当你在各大招聘网站投递简历时,达内学员中有人一毕业进入五百强名企。所以选择很重要。找C++培训班,选达内就对了。
填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!