c++中静态成员变量不存在于对象之中,而存在于全局数据段,只是其可见性受到限制,仅能被所属类访问,而非静态成员变量存在于对象中,因而,在访问两种不同数据成员时,会有些许差别。
对于静态数据成员的访问,是直接操作其所在内存;对于非静态数据成员,则是由对象首地址 + 成员变量相对于对象首地址的偏移量来访问(对涉及到虚拟继承可能更复杂),有一定的间接性。
下面看c++源码:
class X { int X::x1 = 1; int main() { |
其中静态成员变量分了三种方式存取。
下面是main函数对应的汇编码:
; 10 : int main() { push ebp ; 11 : X x; lea eax, DWORD PTR _x$[ebp];获取对象首地址,存入寄存器eax ; 13 : x.x1 = 1; mov DWORD PTR ?x1@X@@2HA, 1 ; 将1赋给?x1@X@@2HA(即静态成员变量x1所在内存)所处的内存 ; 14 : xp->x1 = 2; mov DWORD PTR ?x1@X@@2HA, 2 ; 将2赋给?x1@X@@2HA(即静态成员变量x1所在内存)所处的内存 ; 15 : X::x1 = 3; mov DWORD PTR ?x1@X@@2HA, 3 ; 将3赋给?x1@X@@2HA(即静态成员变量x1所在内存)所处的内存 ; 16 : mov DWORD PTR _x$[ebp+4], 1;将1赋给偏移变量首地址4byte处内存,即将1赋给成员变量x3 ; 18 : xp->x3 = 2; mov ecx, DWORD PTR _xp$[ebp];将指针xp存的值(对象首地址)给寄存器ecx ; 19 : } xor eax, eax |