c++ 中的「柴郡貓技術」(cheshire cat idiom),又稱為 pimpl(pointer to implementation) ,opaque pointer 等,是一種在類中只定義介面,而將私有資料成員封裝在另乙個實現類中的慣用法。該方法主要是為了隱藏類的資料以及減輕編譯時的壓力。
「柴郡貓」是什麼鬼?就是下面這貨:
cheshire cat
柴郡貓的能力和 pimpl 的功能相一致,即雖然資料成員「消失」了(被隱藏了),但是我們的「柴郡貓」的笑容還是可以發揮威力。
下面通過例子來介紹一下 pimpl 。
c++ 中我們在標頭檔案中定義類,比如乙個簡單的 student 類由如下方式定義:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// student.h
class student
;這裡_name
和_age
是student
類的私有資料成員。然而使用該類的客戶往往更關心類的介面(該類能提供哪些服務),我們希望隱藏student
類的私有資料成員,這時候就可以利用 pimpl 模式:定義乙個實現類,將student
類的資料封裝到這個實現類中,同時在student
類中保留乙個指向該實現類的指標變數。用**解釋更清楚:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// student.h
class student
;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// student.cpp
#include "student.h"
#include
#include
using namespace std;
class student::cheshirecat
~cheshirecat() {}
string _name;
int _age;
};student::student() :
_smilecat(
new cheshirecat())
student::~student()
void student::sayhello(std::ostream &out)
string student::getname()
void student::setname(string name)
int student::getage()
void student::setage(int age)
好了,現在student
類的介面沒有任何變化,但是標頭檔案中原有的私有資料成員消失了,只留下乙隻微笑的柴郡貓(cheshirecat *_smilecat;
)。
使用 pimpl 可以幫助我們節省程式編譯的時間。考慮下面這個類:
1
2
3
4
5
6
7
8
9
10
11
12
// a.h
#include "bigclass.h"
#include "verybigclass"
class a
;我們知道c++中有標頭檔案(.h)和實現檔案(.cpp),一旦標頭檔案發生變化,不管多小的變化,所有引用它的檔案都必須重新編譯。對於乙個很大的專案,c++一次編譯可能就會耗費大量的時間,如果**需要頻繁改動,那真的是不能忍。這裡如果我們把bigclass big;
和verybigclass verybig;
利用 pimpl 封裝到乙個實現類中,就可以減少 a.h 的編譯依賴,起到減少編譯時間的效果:
1
2
3
4
5
6
7
8
9
10
11
// a.h
class a
;使用 pimpl 需要在堆空間上分配和釋放記憶體,記憶體開銷增加,同時也需要更多的間接指標跳轉,因此有一些***。
雖然如此,pimpl 仍然是一種實現資料隱藏、減少編譯時間的有效方法。除非會引起顯著的程式效能下降,推薦使用 pimpl 進行設計。
現代 c++ 中不提倡使用 owning raw pointers 和delete
,我們可以用智慧型指標實現 pimpl。
1
2
3
4
5
6
7
8
9
10
// myclass.h
class myclass
;1
2
3
4
5
6
7
8
9
10
11
// myclass.cpp
class myclass::aimpl
;myclass::myclass() : _pimpl(
new aimpl())
posted @
2016-12-16 10:07
心靈捕手 閱讀(
...)
編輯收藏
c 中log的設計
兵馬未動,糧草先行 在進行工程構建前,最先需要考慮的就是日誌系統,用於程式除錯。目前,已經有很多開源庫可供使用 1 其中比較出名的是glog 2 谷歌出品的。我偶爾也寫點程式,之前看到caffee中的日誌模組,我就把它拿了出來 3 以備使用。我最近在寫程式,恰好就把摘出來的日誌模組使用上了。但是我在...
C 中的config設計
配置檔案讀寫類,它要有以下這些方法 1.支援讀入乙個指定配置檔案的能力 2.支援隨時加入乙個配置項的能力 3.足夠強大,能夠寫入各種資料結構的配置資訊 c 裡,我們要儲存這樣的資料就使用 std map 即可。也就是說,我們的 config 類中,需要有乙個最基本最基本的儲存配置檔案鍵值對資訊的 s...
深度學習中的網路設計技術 二 正則化技術
1.什麼是過擬合?什麼是欠擬合?過擬合其實就是在訓練樣本內能夠很好的擬合資料,而在訓練樣本外 沒有參與訓練的樣本 擬合效果很差,這樣的現象就是過擬合。如果你在訓練網路的過程中發現,模型準確率很高,但是在測試的時候發現準確率很低,那麼有可能就是發生了過擬合現象。也就是數過擬合沒有好的泛化能力。泛化 指...