
【C++程序设计技巧】Pimpl机制
发布日期:2021-05-07 23:34:54
浏览次数:20
分类:原创文章
本文共 1731 字,大约阅读时间需要 5 分钟。
作者:出处:
1.简介
这个机制是Private Implementation的缩写,我们常常听到诸如“不要改动你的公有接口”这样的建议,所以我们一般都会修改私有接口,但是这会导致包含该头文件的所有源文件都要重新编译,这会是个麻烦事儿。Pimpl机制,顾名思义,将实现私有化,力图使得头文件对改变不透明。
2.机制分析
首先,我们先看看不使用这个机制的一个实现:
1: // MyBase.h
2: class MyBase {
3: public:
4: int foo();
5: };6:7: // MyDerived.h
8: #include "MyBase.h"
9: class MyDerived : public MyBase {10: public:
11: int bar();
12: };
假设你现在希望在MyBase.h中加入一个新的private和protected成员函数,那么MyDerived和所有包含MyBase.h的源文件都需要重新编译。在一个大工程中,这样的修改可能导致重新编译时间的激增。你可以使用Doxygen或者SciTools看看头文件依赖。
一般来说,不在头文件中包含头文件是一个比较好的习惯,但是这也不能完全消除修改MyBase.h带来的重新编译代价。有没有一个机制可以使得对私有接口做修改时我们可以减小重新编译的代价。
在Pimpl机制中,我们使用前置声明一个Impl类,并将这个类的一个指针实例放入主类中,如下:
1: // MyClass.h
2: class MyClassImpl; // forward declaration3: class MyClass {
4: public:
5: MyClass();6: ~MyClass();7: int foo();
8: private:
9: MyClassImpl *m_pImpl;10: };
现在,除非我们修改MyClass的公有接口,否则这个头文件是不会被修改了。然后,我们用这个Impl类的实现来完成主类的细节实现,在主类的构造函数中,我们完成了实现类指针的实例化:
1: // MyClass.cpp
2: class MyClassImpl {
3: public:
4: int foo() {
5: return bar();
6: }7: int bar() { return var++; }8: int var;
9: };10:11: MyClass::MyClass() : m_pImpl(new MyClassImpl){}
12:13: MyClass::~MyClass()14: {15: try {
16: delete m_pImpl;
17: }18: catch (...) {}
19: }20:21: int MyClass::foo(){ return m_pImpl->foo(); }
Pimpl机制其实这是的一种变种。我们可以对实现类随意的进行增删和修改,而不会导致包含MyClass.h的源代码重新编译。当然,这样做的时间开销和空间开销也是有的。
在实践中,我们常常采用内部类来完成Pimpl机制:
1: // header
2: class fruit
3: {4: public:
5:6: private:
7: class impl;
8: impl* pimpl_;9: }10:11: // implementation
12: class fruit::impl
13: {14:15: };16:17: fruit::fruit()18: {19: pimpl_ = new impl();
20: }
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2025年03月26日 13时15分15秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
大白话说Java反射:入门、使用、原理
2019-03-06
集合系列 Set(八):TreeSet
2019-03-06
JVM基础系列第11讲:JVM参数之堆栈空间配置
2019-03-06
MySQL用户管理:添加用户、授权、删除用户
2019-03-06
比技术还重要的事
2019-03-06
linux线程调度策略
2019-03-06
软中断和实时性
2019-03-06
Linux探测工具BCC(可观测性)
2019-03-06
Opentelemetry Metrics SDK
2019-03-06
流量控制--2.传统的流量控制元素
2019-03-06
SNMP介绍及使用,超有用,建议收藏!
2019-03-06
SDUT2161:Simple Game(NIM博弈+巴什博弈)
2019-03-06
51nod 1596 搬货物(二进制处理)
2019-03-06
来自星星的祝福(容斥+排列组合)
2019-03-06
Hmz 的女装(递推)
2019-03-06
HDU5589:Tree(莫队+01字典树)
2019-03-06
不停机替换线上代码? 你没听错,Arthas它能做到
2019-03-06
sharding-jdbc 分库分表的 4种分片策略,还蛮简单的
2019-03-06
分库分表的 9种分布式主键ID 生成方案,挺全乎的
2019-03-06