一,静态成员变量的存取
静态成员变量只有一个实体,保存在可执行文件的数据段中,如果没有初始化则保存在数据段的BBS中,由于存储在执行文件的数据段中,因此在编译阶段就会确定地址。当程序编译完成后,不管运行多少次,都是一个地址
静态成员变量:可以当做一个全局变量,但是他只在类的空间内可见,引用时用 类名::静态成员变量名
//为了方便查看 反汇编 的代码都执行了些啥,直接将这三行裸体的放在这里,发现其反汇编的代码是一样的,因此说这三种方式是一样的。
Teacher7::m_si = 888888;
008FCA12 mov dword ptr [Teacher7::m_si (0905000h)],0D9038h
tea.m_si = 999999;
008FCA1C mov dword ptr [Teacher7::m_si (0905000h)],0F423Fh
ptea->m_si = 888999;
008FCA26 mov dword ptr [Teacher7::m_si (0905000h)],0D90A7h
class Teacher7 {
public:int m_i;static int m_si;//只是声明,没有定义,因此不分配空间。int m_j;static int m_sj;int m_k;static int m_sk;char m_c;int m_n;
};int Teacher7::m_si = 999;void main() {//静态成员的访问和赋值,如下的三种方式都一样的,可以通过查看汇编来证明cout << Teacher7::m_si << endl;Teacher7 tea;Teacher7* ptea = new Teacher7();cout << tea.m_si << endl;cout << ptea->m_si << endl;Teacher7::m_si = 888;cout << Teacher7::m_si << endl;cout << tea.m_si << endl;cout << ptea->m_si << endl;tea.m_si = 777;cout << Teacher7::m_si << endl;cout << tea.m_si << endl;cout << ptea->m_si << endl;ptea->m_si = 666;cout << Teacher7::m_si << endl;cout << tea.m_si << endl;cout << ptea->m_si << endl;//为了方便查看 反汇编 的代码都执行了些啥,直接将这三行裸体的放在这里Teacher7::m_si = 888888;tea.m_si = 999999;ptea->m_si = 888999;cout << "duandian" << endl;
}
二,非静态成员变量的存储
静态成员变量的存储(普通的成员变量),存放在类的对象总,存取通过类对象,或者类对象指针完成。具体来说是分为:通过类对象的成员函数访问,通过类对象指针的成员函数访问,类对象直接访问,类对象指针直接访问。
这个比较简单,我们就不写例子了。
要注意的是,对于普通成员的访问,编译器本质是 通过:
类对象的首地址 + 成员变量的偏移量 来访问的。
如下图。
我们还可以得出一个结论:在没有虚函数的情况下,在没有父类的情况下:
&Teacher 的值 和 第一个变量的地址是一样的。
在通过成员函数访问成员变量的时候,编译器角度是加上了一个 Teacher * const this的指针。
但是有虚基类的时候,会有不同,后边会讲到。