类的对象模型
类的成员函数与成员变量是分开存储的,类中的成员变量仅是声明,在对象实例化时存储在类对象中,非静态成员函数存储在代码区,静态成员则存储在全局/静态区。
- 每个对象的成员变量都不相同,但每个变量所需要调用的成员函数都是相同的,所以把类的非静态成员函数全部放在代码区,需要调用成员函数时,每个对象自己去代码区域调用即可。这样做的好处是在创建对象时,只要保存成员变量即可,减少了创建变量时所消耗的空间。
- 在sizeof(类名/对象名)时,仅计算类对象的大小即成员变量的大小,计算规则同结构体一样。
- 空类和仅有成员函数的类sizeof时大小为1字节,没有成员变量实例化就是空对象,编译器会用1字节进行占位来避免空对象的产生。
this指针
既然成员函数是存放在公共代码区的,那在调用时又是如何区分不同对象的成员变量呢?
在调用非静态成员函数时会将该对象的地址也一并传入给成员函数做参数,只不过这个过程是隐式发生的。
类名* const this指针就是用来接收对象地址的,同样对用户来说也是透明的。
this指针的特点:
- this指针的类型是:类名* const,即成员函数中不能修改this指针,但可以修改this所指向的内容
- this指针不能在形参和实参显性传递,但是可以在函数内部显性使用
void Display(className* const this) //不能显示传递
{
;
}
void Display()
{
cout << this->_year; //可以在内部显示使用
}
- this指针只能在成员函数的内部使用
- 非静态成员函数只能用对象调用,因为调用需要传入对象的地址又因为this指针不能显示传递
- this指针本质上是成员函数的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
- this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递