PIMPL(private pointer)桥接模式的一种
PIMPL是前向声明的利用,具体含义是利用类的的私有数据类指针隐藏主类的实现细节。
缺点:
1)增加指针,暂用过多的内存
2)需要较多的指针跳转
优点1:
1)降低模块的耦合。因为隐藏了类的实现,被隐藏的类相当于原类不可见,对隐藏的类进行修改,不需要重新编译原类。
2)降低编译依赖,提高编译速度。指针的大小为(32位)或8(64位),X发生变化,指针大小却不会改变,文件c.h也不需要重编译。
3)接口与实现分离,提高接口的稳定性。
1、通过指针封装,当定义“new C”或"C c1"时 ,编译器生成的代码中不会掺杂X的任何信息。
2、当使用C时,使用的是C的接口(C接口里面操作的类其实是pImpl成员指向的X对象),与X无关,X被通过指针封装彻底的与实现分离。
//x.h class X { public: void Fun(); private: int i; //add int i; }; //c.h #include <x.h> class C { public: void Fun(); private: X x; //与X的强耦合 }; PIMPL做法: //c.h class X; //代替#include <x.h> class C { public: void Fun(); private: X *pImpl; //pimpl };
优点2:保证接口的稳定性,我们常常听到诸如“不要改动你的公有接口”这样的建议,所以我们一般都会修改私有接口,但是这会导致包含该头文件的所有源文件都要重新编译,这会是个麻烦事儿。Pimpl机制,顾名思义,将实现私有化,力图使得头文件对改变不透明
// 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.cpp
2: class MyClassImpl {
3: public:
4: int foo() {
5: return bar();
6: }
7: int bar() { return var++; }
8: int var;
9: };
11: MyClass::MyClass() : m_pImpl(new MyClassImpl){
13: MyClass::~MyClass()
14: {
15: try {
16: delete m_pImpl;
17: }
18: catch (...) {}
19: }
21: int MyClass::foo(){ return m_pImpl->foo(); }
通过以上编码,保证头文件稳定性,可以对实现类m_pimpl随意的修改,当实现文件重新编译时,包含头文件Myclass.h的其他文件不需要重新编译。从而实现了接口的稳定性。在实践中一般采用内部类来是实现
// header 2: class fruit 3: { 4: public: 5: 6: private: 7: class impl;//声明内部类 8: impl* pimpl_; 9: } 10: 11: // implementation 12: class fruit::impl//在fruit的实现文件中,实现 13: { 14: 15: }; 16: 17: fruit::fruit() 18: { 19: pimpl_ = new impl(); 20: }
浙公网安备 33010602011771号