一、普通静态成员函数的调用方法
栗子:
class CA
{
public:
static void func() {}
};
int main()
{
CA A;
A.func();
CA::func();
return 0;
}
查看汇编代码,如下:
12: A.func();
001E20F8 call CA::CA (01E14C4h)
13: CA::func();
001E20FD call CA::CA (01E14C4h)
由此可知,上述两种方法调用静态函数是相同的,直接通过地址调用。
二、静态成员函数的符号表达
栗子:
class A
{
public:
virtual void fun1() {}
void fun2() {}
static void fun3() {}
};
void fun4() {}
执行 nm 命令,得到
000000000000073a T _Z4fun4v
00000000000007a0 W _ZN1A4fun1Ev
00000000000007ac W _ZN1A4fun2Ev
00000000000007b7 W _ZN1A4fun3Ev
综上,普通成员函数、虚函数、静态成员函数对于编译器来说,命名规则都是一样的,均可以看成重命名之后带有类名的全局函数。
不同点如下:
(1)调用方式:
a、普通成员函数只能直接调用;
b、虚函数的调用方式:
- 直接调用。
- 通过查询虚函数表调用。
c、静态成员函数只能直接调用。
(2)是否含有 this 指针。
a、普通成员函数:有
b、虚函数:有
c、静态函数:无
由于静态成员函数没有 this 指针,这就导致了如下性质:
a、不能直接调用非静态成员变量。
b、不能直接调用非静态的成员函数。
c、不能是虚函数。
static成员不属于任何类对象或类实例,所以即使给此函数加上virutal也是没有任何意义的。
虚函数依靠vptr和vtable来处理。vptr是一个指针,在类的构造函数中创建生成,并且只能用this指针来访问它,因为它是类的一个成员,并且vptr指向保存虚函数地址的vtable。
对于静态成员函数,它没有this指针,所以无法访问vptr。这就是为何static函数不能为virtual.
虚函数的调用关系:this -> vptr -> vtable ->virtual function 。
d、不能是 const 。这是C++的规定,带 const 的成员函数,是不能修改对象的非静态成员变量的。既然静态函数都不能访问非静态的成员变量,也就无从谈起是 const 函数。
static 应用场景
全局函数、全局变量:只能被本文件的函数所调用。
局部变量:不会在函数终止时丢失。
成员变量:类的属性,所有该类对象只有这一个实例。
成员函数:类的属性,无 this 指针。
(SAW:Game Over!)