类对象模型和this指针

关于类/对象大小的计算

类只是一种类型定义,它本身是没有大小可言的。 我们这里指的类的大小,其实指的是类的对象所占的大小。因此,如果用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小。

  1. 首先,类大小的计算遵循结构体的对齐原则
  2. 类的大小与普通数据成员有关,与成员函数和静态成员无关。即普通成员函数,静态成员函数,静态数据成员,静态常量数据成员均对类的大小无影响
  3. 虚函数对类的大小有影响,是因为虚函数表指针带来的影响
  4. 虚继承对类的大小有影响,是因为虚基表指针带来的影响
  5. 空类的大小是一个特殊情况,空类的大小为1

类对象的存储方式

静态数据成员之所以不计算在类的对象大小内,是因为类的静态数据成员被该类所有的对象所共享,并不属于具体哪个对象,静态数据成员定义在内存的全局区。同样的类中的成员函数是相同的,对于每一新生成的对象,没有必要为其再存储一份相同的成员函数,成员函数存放在公共代码区
在这里插入图片描述

class A1 { //sizeof(A1) = 4
public:
	void f1(){}
private:
	int _a;
};
// 类中仅有成员函数
class A2 {//sizeof(A2) = 1
public:
	void f2() {}
};
// 类中什么都没有---空类
class A3//sizeof(A3) = 1
{};

class base
{//sizeof(base) = 8
    private:
    static int a;
    int b;
    char c;

};

注意:派生类继承空类 和一个类包含为空类的成员函数

class Empty {};
struct D : public Empty { int a;};//sizeof(D) = 4

class Empty {};
class HoldsAnInt {
//sizeof(HoldsAnInt) = 8
    int x;
    Empty e;
};

含有虚函数成员

虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。编译器必需要保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证正确取到虚函数的偏移量)。
  每当创建一个包含有虚函数的类或从包含有虚函数的类派生一个类时,编译器就会为这个类创建一个虚函数表(VTABLE)保存该类所有虚函数的地址,其实这个VTABLE的作用就是保存自己类中所有虚函数的地址,可以把VTABLE形象地看成一个函数指针数组,这个数组的每个元素存放的就是虚函数的地址。在每个带有虚函数的类 中,编译器秘密地置入一指针,称为v p o i n t e r(缩写为V P T R),指向这个对象的V TA B L E。 当构造该派生类对象时,其成员VPTR被初始化指向该派生类的VTABLE。所以可以认为VTABLE是该类的所有对象共有的,在定义该类时被初始化;而VPTR则是每个类对象都有独立一份的,且在该类对象被构造时被初始化。

class Base {//sizeof = 4
public:

	virtual void f() { cout << "Base::f" << endl; }

	virtual void g() { cout << "Base::g" << endl; }

	virtual void h() { cout << "Base::h" << endl; }

};
发布了89 篇原创文章 · 获赞 11 · 访问量 5319

猜你喜欢

转载自blog.csdn.net/weixin_44997886/article/details/103362977