【 聲明:版權所有,歡迎轉載,請勿用於商業用途。 聯系信箱:feixiaoxing @163.com】
看過設計模式的朋友都知道,我們在設計單件模式的時候離不開類的靜態函數。和類的成員變量不同,類的靜態變量屬於全部類對象數據;同樣和類的成員函數不同,類的靜態函數屬於全部類函數共有。這句話讀來想來有一些拗口,不過沒有關系,我們可以通過一段代碼來說明問題。
(1)靜態變量
老規矩,我們首先對類進行初步定義,如下所示:
class employee
{
public:
employee() { }
~employee() {}
static int value;
};
class employee
{
public:
employee() { }
~employee() {}
static int value;
}; 那麼,這裡出現的value是不是所共有的,我們可以看看相關的函數代碼即可:
67: int employee::value = 0;
68:
69: void process()
70: {
00401240 push ebp
00401241 mov ebp,esp
00401243 push 0FFh
00401245 push offset __ehhandler$?process@@YAXXZ (0041f469)
0040124A mov eax,fs:[00000000]
00401250 push eax
00401251 mov dword ptr fs:[0],esp
00401258 sub esp,48h
0040125B push ebx
0040125C push esi
0040125D push edi
0040125E lea edi,[ebp-54h]
00401261 mov ecx,12h
00401266 mov eax,0CCCCCCCCh
0040126B rep stos dword ptr [edi]
71: employee m;
0040126D lea ecx,[ebp-10h]
00401270 call @ILT+35(employee::employee) (00401028)
00401275 mov dword ptr [ebp-4],0
72: employee n;
0040127C lea ecx,[ebp-14h]
0040127F call @ILT+35(employee::employee) (00401028)
73:
74: m.value = 10;
00401284 mov dword ptr [employee::value (00438494)],0Ah
75: n.value = 100;
0040128E mov dword ptr [employee::value (00438494)],64h
76: }
00401298 lea ecx,[ebp-14h]
0040129B call @ILT+0(employee::~employee) (00401005)
004012A0 mov dword ptr [ebp-4],0FFFFFFFFh
004012A7 lea ecx,[ebp-10h]
004012AA call @ILT+0(employee::~employee) (00401005)
004012AF mov ecx,dword ptr [ebp-0Ch]
004012B2 mov dword ptr fs:[0],ecx
004012B9 pop edi
004012BA pop esi
004012BB pop ebx
004012BC add esp,54h
004012BF cmp ebp,esp
004012C1 call __chkesp (004086b0)
004012C6 mov esp,ebp
004012C8 pop ebp
004012C9 ret
67: int employee::value = 0;
68:
69: void process()
70: {
00401240 push ebp
00401241 mov ebp,esp
00401243 push 0FFh
00401245 push offset __ehhandler$?process@@YAXXZ (0041f469)
0040124A mov eax,fs:[00000000]
00401250 push eax
00401251 mov dword ptr fs:[0],esp
00401258 sub esp,48h
0040125B push ebx
0040125C push esi
0040125D push edi
0040125E lea edi,[ebp-54h]
00401261 mov ecx,12h
00401266 mov eax,0CCCCCCCCh
0040126B rep stos dword ptr [edi]
71: employee m;
0040126D lea ecx,[ebp-10h]
00401270 call @ILT+35(employee::employee) (00401028)
00401275 mov dword ptr [ebp-4],0
72: employee n;
0040127C lea ecx,[ebp-14h]
0040127F call @ILT+35(employee::employee) (00401028)
73:
74: m.value = 10;
00401284 mov dword ptr [employee::value (00438494)],0Ah
75: n.value = 100;
0040128E mov dword ptr [employee::value (00438494)],64h
76: }
00401298 lea ecx,[ebp-14h]
0040129B call @ILT+0(employee::~employee) (00401005)
004012A0 mov dword ptr [ebp-4],0FFFFFFFFh
004012A7 lea ecx,[ebp-10h]
004012AA call @ILT+0(employee::~employee) (00401005)
004012AF mov ecx,dword ptr [ebp-0Ch]
004012B2 mov dword ptr fs:[0],ecx
004012B9 pop edi
004012BA pop esi
004012BB pop ebx
004012BC add esp,54h
004012BF cmp ebp,esp
004012C1 call __chkesp (004086b0)
004012C6 mov esp,ebp
004012C8 pop ebp
004012C9 ret
我們直接看74行和75行。我們看到復制的對象地址都是驚人的一致,這說明實際上m和n所指的value實際上是同一個地址0x401005。不過,類的靜態對象有一個要求,那就是對象的靜態變量必須像全局變量一樣進行初始化操作。
(2)靜態函數
靜態函數和靜態變量一樣,實際上就是類的全局函數。它之所以和普通的成員函數不一樣,就是因為它不需要定義類的類型就能使用這個函數。根據上面的信息,我們可以重新定義一下這個類:
class employee
{
public:
employee() { }
~employee() {}
static void print() { printf("employee::print()!\n");};
};
class employee
{
public:
employee() { }
~employee() {}
static void print() { printf("employee::print()!\n");};
}; 那麼類的靜態函數是這樣使用的呢?大家看看下面這樣一個函數:
68: void process()
69: {
00401230 push ebp
00401231 mov ebp,esp
00401233 sub esp,40h
00401236 push ebx
00401237 push esi
00401238 push edi
00401239 lea edi,[ebp-40h]
0040123C mov ecx,10h
00401241 mov eax,0CCCCCCCCh
00401246 rep stos dword ptr [edi]
70: employee::print();
00401248 call @ILT+0(employee::print) (00401005)
71: }
0040124D pop edi
0040124E pop esi
0040124F pop ebx
00401250 add esp,40h
00401253 cmp ebp,esp
00401255 call __chkesp (00408620)
0040125A mov esp,ebp
0040125C pop ebp
0040125D ret
68: void process()
69: {
00401230 push ebp
00401231 mov ebp,esp
00401233 sub esp,40h
00401236 push ebx
00401237 push esi
00401238 push edi
00401239 lea edi,[ebp-40h]
0040123C mov ecx,10h
00401241 mov eax,0CCCCCCCCh
00401246 rep stos dword ptr [edi]
70: employee::print();
00401248 call @ILT+0(employee::print) (00401005)
71: }
0040124D pop edi
0040124E pop esi
0040124F pop ebx
00401250 add esp,40h
00401253 cmp ebp,esp
00401255 call __chkesp (00408620)
0040125A mov esp,ebp
0040125C pop ebp
0040125D ret
靜態函數不需要對應的類對象,所以也就不需要this指針。這就是成員函數和靜態函數的區別,僅此而已。