
【C++程序设计技巧】Pimpl机制
发布日期:2021-05-07 23:34:54
浏览次数:23
分类:精选文章
本文共 1723 字,大约阅读时间需要 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 declaration 3: 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年04月15日 20时12分48秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Kubernetes学习总结(5)——Kubernetes 常见面试题汇总
2023-01-29
Kubernetes实战(一)-Kubernetes集群搭建
2023-01-29
Kubernetes实战(三十一)-Calico网络部署(推荐)
2023-01-29
Kubernetes实战(三十三)-外部Etcd集群部署与调优(更安全的数据存储策略)
2023-01-29
Kubernetes实战(二十九)-集群资源管理(CPU & Memory)
2023-01-29
Kubernetes快速上手:部署、使用及核心概念解析
2023-01-29
lamp 一键安装
2023-01-30
laravel mix
2023-01-30
Laravel Passport
2023-01-30
laravel 之 Eloquent 模型修改器和序列化
2023-01-30
Laravel 使用rdkafka
2023-01-30
Laravel 多环境配置
2023-01-30
Laravel 安装上传代码不完整的解决方法
2023-01-30
Laravel 深入理解路由和URL生成
2023-01-30
laravel 生命周期与框架精髓
2023-01-30