【C++总结记载】类对象、继承、虚继承、虚函数表

关于虚函数表,可见博客    传送    ,但是要注意,一般被继承的第一个基类的虚函数表合并至子类的虚函数表,(基类的虚函数在前,除非有虚函数覆盖,子类的虚函数在后)

主要讲了在无虚继承情况下各种情况的虚函数表的情况,

因此,就牵扯到了类的大小的问题:

1)对于一个空类,sizeof=1;

2)静态成员不属于类大小中,且成员函数也不属于类大小中

3)类与继承情况下类的大小:

情况一:   无虚函数继承,但有虚函数的情况

class A 
{
public:
	char a[3];	
	virtual void fa() {};
};

class B :  public  A
{
public:
	char b[3];
	virtual void fa() {};
	
};

class C : public  A
{
public:
	char c[3];	
	virtual void bb() {};
};


int main() {
	
	cout << sizeof(A) << endl;
	cout << sizeof(B) << endl;
	cout << sizeof(C) << endl;
}

结果是:VS2015   debug   x86

sizeof(A) = 8   

              = A的虚函数表指针的4字节+char对齐的4字节

sizeof(B) = 12   

              = B的虚函数表指针的4字节 + 类B中char对齐的4字节+类A中char对齐的4字节 

sizeof(C) = 12   

              = C的虚函数表指针的4字节 + 类C中char对齐的4字节+类A中char对齐的4字节 

情况二:   虚函数继承,有虚函数的情况

class A 
{
public:
	char a[3];	
	virtual void fa() {};
};

class B :  virtual public  A
{
public:
	char b[3];
	virtual void fa() {}; //虚函数覆盖
	
};

class C : virtual public  A
{
public:
	char c[3];	
	virtual void bb() {}; //无虚函数覆盖
};

class D :public B, public C
{
public:
	char d[3];
	
};

int main() {
	
	cout << sizeof(A) << endl;
	cout << sizeof(B) << endl;
	cout << sizeof(C) << endl;
	cout << sizeof(D) << endl;
}

虚继承:虚继承的提出是为了解决多重继承时,可能会保存两份副本的问题,也就是说用了虚继承就只保留了一份副本,但是这个副本是被多重继承的基类所共享的。

虚继承底层实现原理与编译器相关,一般通过虚基类指针和虚基类表实现,每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝,只是仅仅最多存在一份而已,并不是不在子类里面了);当虚继承的子类被当做父类继承时,虚基类指针也会被继承。

因此 :要考虑虚函数表指针和虚基类指针

结果是:VS2015   debug   x86

sizeof(A) = 8   

              = A的虚函数表指针的4字节+char对齐的4字节

sizeof(B) = 16  

              = B的虚函数表指针的4字节(合并类A覆盖的虚函数) +A的虚基类指针4字节+类B中char对齐的4字节 + 类A中char对齐的4字节

sizeof(C) = 20   

              = C的虚函数表指针的4字节(合并类A覆盖的虚函数) +A的虚基类指针4字节+类C中char对齐的4字节 +类A的虚函数表指针(没覆盖的虚函数)+ 类A中char对齐的4字节

sizeof(D) = 32

             = 类D的虚函数表指针的4字节(和类B的虚函数表合并) +类D中char对齐的4字节 +类B中的虚基类指针4字节+类B中char对齐的4字节+类C中的虚基类指针4字节+类C虚函数表指针4字节+类C中char对齐的4字节+ 共享类A中char对齐的4字节


猜你喜欢

转载自blog.csdn.net/Neo_dot/article/details/80725800