版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
看过设计模式的朋友都知道,我们在设计单件模式的时候离不开类的静态函数。和类的成员变量不同,类的静态变量属于全部类对象数据;同样和类的成员函数不同,类的静态函数属于全部类函数共有。这句话读来想来有一些拗口,不过没有关系,我们可以通过一段代码来说明问题。
(1)静态变量
老规矩,我们首先对类进行初步定义,如下所示:
-
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)
-
004012A
0 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 (
004086b
0)
-
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");};
-
};
那么类的静态函数是这样使用的呢?大家看看下面这样一个函数:
-
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 (
0040862
0)
-
0040125A mov esp,ebp
-
0040125C
pop ebp
-
0040125D ret
静态函数不需要对应的类对象,所以也就不需要this指针。这就是成员函数和静态函数的区别,仅此而已。
【预告: 下面一篇博客介绍类的算术重载符】