栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++编程技巧之Pimpl手法

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++编程技巧之Pimpl手法

一、Pimpl是什么

Pimpl全称是point to implementation,译为指向实现的指针;是一种c++程序技巧。
其具有如下基本形式:

class widget {
    // 其它部分
private:
    struct impl;        // 前置申明一种变量类型
    impl* pimpl_;       // 定义该类型的指针或引用,用这个pimpl_来隐藏类widget的一些实现细节
};
二、为什么需要Pimpl技术

我们知道,在C/C++中,声明变量是不占用内存的,只有定义变量时,编译器才会为相应的变量分配对应的内存;对于一个C++的类class来说,也是如此。当在类内部定义成员变量时,会影响整个类的内存大小等相关因素;因此,若修改了类中的相关定义实现,即使该实现是private成员这是或者private函数,那么包含这个类的所有用户代码都会被重新编译;因为这些代码依赖于当前类的实现细节。
因此,为了减小编译时的依赖,就可以运用这种Pimpl技术;从其基本的定义形式就可以看出,其大小固定为一个指针大小,而指针所指对象的变化并不影响使用该指针的类的大小,这样一来,用这个impl指针来包裹类widget中容易变动的实现细节,在更改impl对象时,并不影响外部用户代码的编译;其可以带来两个好处:

第一,打破编译依赖,可以使整个系统代码编译速度更快;第二,其隐藏了内部实现细节的同时,也提高了代码修改的灵活度。 三、怎么使用Pimpl技术

为了使用Pimpl技术,其基本的使用形式如下:

// in header file,即相应的.h头文件
class widget {
public:
    widget();
    ~widget();
private:
    class impl;
    unique_ptr pimpl;
};
 
// in implementation file,即相应的.cpp/.cxx等文件
class widget::impl {
    // :::
};
 
widget::widget() : pimpl{ new impl{  } } { }
widget::~widget() { } 

其使用细节准则如下:

(1)使用std::unique_ptr来管理相应的pimpl指针,这是为了更好的内存管理,避免未翻放相应内存;更详细的原理,可以查阅《Effective C++》第三版的条款13项,以对象管理资源的理念;(2)在.cpp文件中定义实现widget::impl类,以达到隐藏实现细节和减少编译依赖的目的;(3)在.cpp文件中,要显式定义widget::widget和widget::~widget函数,避免编译器默认生成;同样的,对于拷贝构造和赋值构造,若不想被使用,应该申明为私有;若需要被使用,也要显式定义。(4)将widget中所有私有的非虚成员放入impl中去定义和实现;这也是符合OOP编程思想的理念;在OOP编程中,public成员,是为了给外部代码使用;protect和virtual成员是为了给子类继承和修改;而其它私有非虚成员,则是类的实现细节,不影响对外暴露;(5)若impl类中需要访问widget的public成员,则将widget对象作为impl的成员函数的参数,进行传递;一般采用widget指针或者widget引用参数;


四、优缺点总结

优点:

解除了接口和实现之间的偶合,隐藏了实现细节;减少了编译依赖性,提高编译速度;更高修改实现的灵活度,而不用考虑外部用户代码。

缺点:

widget的public成员函数需要通过impl指针,进一步访问对象数据,添加了一层间接性;每一个widget对象,相比于最原始实现,至少多消耗一个impl指针大小的内存;widget对象必须初始化impl指针成员,动态分配impl对象;因此,也增加了动态内存分配内存(及后续释放内存)的额外开销;


参数文献:
https://en.cppreference.com/w/cpp/language/pimpl PImpl说明
https://herbsutter.com/gotw/_100/ Compilation Firewalls;
《Effective C++》第三版,条款13,条款31等;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/784250.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号