介紹一個C++中非常有用的設計模式
本文轉載自微信公眾號「程序喵大人」,作者程序喵大人。轉載本文請聯系程序喵大人公眾號。
大家好,今天介紹一個C++中非常常用的模式:pimpl
至于它有什么作用,直接看代碼:
- // MyClass.h
- class MyClass {
- public:
- void func1();
- void func2();
- private:
- void func3();
- void func4();
- int a;
- int b;
- };
假設我們在開發(fā)一個SDK,或者設計某個模塊,需要暴露出去一個MyClass.h頭文件,并向用戶提供func1和func2兩個功能。
但是MyClass中還有一些private函數和字段,這些函數和字段我們本意可能是不想被用戶知道,因為可能里面有些隱私內容,用戶有可能通過這些private方法和字段就能猜到我們的架構及實現。
這也是我們平時設計模塊需要注意的一點:只暴露出該暴露的東西。
那怎么做呢?答案就是pimpl模式。
可以這樣:
- // MyClass.h
- class MyClass {
- public:
- void func1();
- void func2();
- private:
- class impl;
- impl* pimpl;
- };
- // MyClass.cc
- class MyClass::impl {
- public:
- void func1();
- void func2();
- private:
- void func3();
- void func4();
- int a;
- int b;
- };
- MyClass::MyClass() {
- pimpl = new impl;
- }
- void MyClass::func1() {
- pimpl->func1();
- }
將類的private屬性隱藏進一個內部類,然后通過一個指針訪問(提前聲明)它的接口。在頭文件中只暴露出應該暴露的功能,然后持有一個Impl的指針,而Impl則具體在MyClass.cc中定義,用戶什么都看不到。然后所有的功能都通過Impl完成。頭文件里的Impl的指針也可以通過智能指針(unique_ptr)來代替,但這不是本文的重點。
再總結一下pimpl模式的優(yōu)點:
- 非常適合隱藏private實現:如果想要在頭文件中暴露public接口,但又不想暴露private實現的細節(jié),則可以使用pimpl模式來隱藏細節(jié)。
- pimpl模式也被稱為編譯防火墻,是一種用來減少編譯時間的方法。通常來講,如果頭文件里的某些內容變更了,意味著所有引用該頭文件的代碼都要被重新編譯,即使變更的是無法被用戶類訪問的私有成員。將這部分代碼從被引用多次的頭文件里移除到只被引用編譯一次的源文件中,更改此文件就不會付出太長的編譯時間。
大家怎么看?
參考資料
https://en.cppreference.com/w/cpp/language/pimpl