Cpp 对象模型探索 / 类静态成员函数的调用方式
一、普通靜態成員函數的調用方法
栗子:
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!)
總結
以上是生活随笔為你收集整理的Cpp 对象模型探索 / 类静态成员函数的调用方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cpp 对象模型探索 / 虚函数的调用方
- 下一篇: Cpp 对象模型探索 / 多态的本质