C++虚表再探

单继承

1、一个类

#include <iostream>
using namespace std;
class A {
	int a;
	virtual void run() {
		cout << 1 << endl;
	}
};

如果是一个类的话,我们定义了一个虚函数,就会有虚表对应产生,该类记录虚表的地址(四个字节),我们输出sizeof(A)是8,如果不是虚函数就没有虚表对应产生。
如果对于该类并没有涉及到多态和虚函数,就不会存储虚表指针。
我们查看类A的虚表情况:
在这里插入图片描述
如果没有虚函数,类A只有一个a变量:
在这里插入图片描述
类A没有继承,也没有虚函数,所以没有对应的虚表。

2、B继承A

首先我们要明确,虚表是针对本类的,本类存储的虚表。这个类的虚表就直接确定了,跟指向这个类对象的指针没有什么关系。

class A {
	int a;
	virtual void run() {
		cout << 1 << endl;
	}
};
class B :public A{
	int b;
	void run() {
		cout << 2 << endl;
	}
	virtual void run2() {
		cout << 3 << endl;
	}
}

上面是最简单的继承,A的虚表和刚刚分析的一样。我们分析B的虚表,它的sizeof是12字节,因为包含了a,b,虚表指针。
因为run函数实现了override,所以虚表中会有B中的run函数入口,run2函数入口。如图所示:
在这里插入图片描述
此时指向B对象的指针,调用run,run2都是B类的。
如果我们把B中的run函数删去。

在这里插入图片描述
如果把A中的virtual去掉:
在这里插入图片描述
跟虚函数无关的函数,不会出现在虚表里面,它不会进行动态绑定。
现在给我们一个类,我们可以去刻画它的虚表什么样子了:

(1)、基类较为简单,虚函数都放进去。
(2)、派生类的虚表,我们可以从结果来分析。
如果单独属于派生类,且是虚函数,那会出现在虚表里面。
如果单独属于基类,且是虚函数,会出现在虚表里面。
如果实现了多态,那么派生类的函数会出现在虚表里面。

多继承

1、简单多继承

class A {
	int a;
	virtual void run() {
		cout << 1 << endl;
	}
};
class B{
	int b;
	virtual void run() {
		cout << 2 << endl;
	}
};
class C :public B,public A {
	void run() {
		cout << 3 << endl;
	}
};

多继承最简单的例子:
我们分析,C继承了A的a,B的b。
函数方面,实现了A和Brun函数的重写(多态)。
看过虚表之后,发现与单继承一致,只不过C不再试只有一个虚表。
C存储两个虚表,一个基于A,一个基于B,所以sizeof©为16。
在这里插入图片描述
分析多继承的时候,还是可以看成单继承。对每个父类和自己的关系进行逐个分析,如图所示都实现了run函数的重写。学会了单继承的分析,多继承分析方法一致。

2、复杂多继承(在上面基础上加上B:A)

分析方法同样可以根据结果进行分析,不做详细说明。

这个虚表和内存展示工具:

Vs自带的command prompt。我版本2017,直接可以搜索到。
在这里插入图片描述
还有推荐左耳朵耗子的博客:
https://blog.csdn.net/haoel/article/details/1948051

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值