C++学习 对象模型之虚基类,虚基类表,虚基类表指针

1.虚基类

什么是虚基类,虚基类的作用是什么?
首先虚基类是为了解决多继承产生的二义性问题,范例代码如下:

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <Windows.h>
using namespace std;

class Base {
public:
	int m_base_a;
};


class A :public Base {
public:
	int m_A_a;
};
class B :public Base {
public:
	int m_B_a;
};

class Derived :public A, public B {
public:
	int m_D_a;
};

int main() {

	Derived *b = new Derived();
	b->m_base_a = 10;

	return 0;
}

在这里插入图片描述

此时编译代码会报错,因为子类Derived对象有两份爷爷类Base的对象内存,一份是A类继承而来,一份是B类继承而来。在这里编译器无法判断当前需要赋值的m_base_a是来自A还是B。如果改成b->A::m_base_a = 10;则编译器不会报错,但是对于子类Derived另一份Base对象是多余的,造成了内存的浪费。因此C++引入了虚基类来解决这个问题,当子类继承多个类,且多个父类都继承一个爷爷类时,子类对象就保留一份爷爷对象空间。父类在继承爷爷类需要加上virtual关键字,具体代码如下:

class Base {
public:
	int m_base_a;
};


class A :virtual public Base {
public:
	int m_A_a;
};
class B :virtual public Base {
public:
	int m_B_a;
};

class Derived :public A, public B {
public:
	int m_D_a;
};

int main() {

	Derived *b = new Derived();
	b->m_base_a = 10;

	return 0;
}

其中Base 就是虚基类

2.虚基类表和虚基类表指针

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <Windows.h>
using namespace std;

class Base {
public:
	int m_base_a;
};


class A :virtual public Base {
public:
	int m_A_a;
};
class B :virtual public Base {
public:
	int m_B_a;
};

class Derived :public A, public B {
public:
	int m_D_a;
};

int main() {

	Derived *b = new Derived();
	cout << "Base sizeof " << sizeof(Base) << " A sizeof  " << sizeof(A) << " B sizeof " << sizeof(B) << "Derived sizeof " << sizeof(Derived)<<endl;
	b->m_base_a = 10;

	return 0;
}

在这里插入图片描述

打印这三个类对象的内存占用大小:
class Base大小为4字节好理解,就是m_base_a占用的大小。
class A的大小12字节,其中继承Base成员m_base_a占四字节,自己成员m_A_a占用,还有四字节就是虚基类表指针
class B与A一样
最后子类Derived对象大小为24字节,其中m_base_a,m_A_a,m_B_a,m_D_a占16字节,还有8字节时继承A和B类的虚基类表指针

说明:虚基类表一般是8字节,每多一个虚基类就多4字节,虚基类表其实就是存储虚基类对象在子类对象的偏移量,让子类对象能够访问到虚基类对象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值