明白了虚函数

本文探讨了C++中虚继承和普通继承的内存布局差异。通过VS编译器的/d1reportSingleClassLayout选项查看类的内存分布,发现虚继承减少了内存冗余,而普通继承会导致每个子类复制基类的数据成员。虚函数表和虚基类表在多态和内存管理中起到关键作用,影响类的大小和继承层次的内存布局。
摘要由CSDN通过智能技术生成

一、新建两个cpp文件,一个是普通继承(没有使用虚基类),一个是虚继承(虚基类)

/**
	虚继承(虚基类)
	VirtualClass.cpp
*/
#include <iostream>
 
// 基类A
class A
{
public:
	int dataA;
};
 
class B : virtual public A
{
public:
	int dataB;
};
 
class C : virtual public A
{
public:
	int dataC;
};
 
class D : public B, public C
{
public:
	int dataD;
};
/**
    普通继承(没有使用虚基类)
    NormalClass.cpp
*/

// 基类A
class A
{
public:
    int dataA;
};

class B : public A
{
public:
    int dataB;
};

class C : public A
{
public:
    int dataC;
};

class D : public B, public C
{
public:
    int dataD;
};

二、 VS编译器查看内存分布

1、工具(T)Visual Studio 命令提示©

2、进入所查看cpp文件的目录

3、输入命令 cl --cpp文件名 --/d1reportSingleClassLayout–类名

在这里插入图片描述
cl VirtualClass.cpp /d1reportSingleClassLayoutD
在这里插入图片描述
cl VirtualClass.cpp /d1reportSingleClassLayoutB
在这里插入图片描述

cl VirtualClass.cpp /d1reportSingleClassLayoutC

在这里插入图片描述

cl NormalClass.cpp /d1reportSingleClassLayoutD
在这里插入图片描述
cl NormalClass.cpp /d1reportSingleClassLayoutB在这里插入图片描述

vbtable指的是虚基类表(virtual base table pointer)
vbptr指的是虚基类表指针(virtual base table pointer),该指针指向了一个虚表(virtual table),
表头位置

如果我们声明了一个类,里面有虚函数,则会生成一个虚函数表和一个虚函数表指针,按虚函数声明顺序依次加入
虚函数表中。

当有虚函数的基类被子类继承以后,子类也会继承基类的指针和虚函数表,如上图的虚继承的D类
先继承B,再继承C
在内存中的分布,先B,再C,再本身D,再到最远基类A
如果在子类有对继承的虚函数进行重写,则会替换虚函数表里面对应的虚函数

```cpp
class A {
public:
	virtual void print(){
		cout << "in class A" << endl;
	};
};

class B :public A {
public:
	void print(){
		cout << "in class B" << endl;
	};
};

A *a1 = new A;//a是A类型的指针指向一个A类型的对象
A *a2 = new B;//a是A类型的指针指向一个B类型的对象
//B *b1 = new A;--“A*类型的值不能用于初始化B类型的实体”
B *b2 = new B;//b是B类型的指针指向一个B类型的对象

在这里插入图片描述

指针指向那个类,我们就用那个类的虚函数表,与指针本身无关,这也就是虚函数多态的形成。
相对于普通继承,继承一次就要在内存中全部拷贝一份,造成冗余,而虚继承最多的消耗只是指针
(一般情况下,虚函数表的内存消耗可以忽略)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoduangg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值