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

























