C++---继承与多态2

本文详细探讨了C++中的继承与多态特性,包括虚函数、虚函数表(vftable)、虚表合并、运行时多态、抽象类与纯虚函数、虚析构函数以及类型转换等概念。重点讲解了虚函数如何实现动态绑定,以及为何需要将析构函数声明为虚函数以避免内存泄漏问题。此外,还提到了多继承、虚继承及其内存布局,并讨论了如何防止一个类被继承的方法。
摘要由CSDN通过智能技术生成

1.虚函数

 首先,我们看一下当Base*指向Derive对象时,而Base类中含有虚函数时,基类和派生类大小、基类和派生类指针(引用)的类型。

#include <iostream>
#include <typeinfo>
using namespace std;
 
class Base
{
public:
	Base(int a = 1)
	{
		ma = a;
	}
	virtual void show()
	{
		cout<<"base show 1"<<endl;
	}
	void show(int b)
	{
		cout<<"base show 2"<<endl;
	}
private:
	int ma;
};
 
class Derive : public Base
{
public:
	Derive(int b = 2):Base(b)
	{
		mb = b;
	}
	void show()
	{
		cout<<"derive show 1"<<endl;
	}
	
private:
	int mb;
};
 
int main()
{
	Base b;
	Derive d;
	Base* p = &d;
	cout<<"base size:"<<" "<<sizeof(b)<<endl;
	cout<<"derive size:"<<" "<<sizeof(d)<<endl;
	cout<<"p type:"<<" "<<typeid(p).name()<<endl;
	cout<<"*p type:"<<" "<<typeid(*p).name()<<endl;
	return 0;
}

结果如下:

基类的大小和父类的大小都增加了4个字节。并且当Base*指向Derive对象时,*Base的类型却变为Derive,不再和指针本身的类型相关,这是怎么回事呢?

2.虚函数指针 vfptr

 实际上,Base和Derive类增加的4个字节就是虚函数指针的大小,每一个类只要有虚函数(包括继承而来的),它就有且只有一个虚函数指针,类的大小就是总的成员变量的大小加上一个虚函数指针的大小。虚函数指针指向的是一张虚表,里面是这个类所有虚函数的地址,一个类对应一张虚函数表,而虚函数指针存在于每一个对象中,并且永远占据对象内存的前四个字节。

首先我们先看下Base类(虚函数指针优先级最高)

                        

3. 虚函数表vftable
    虚函数表又称为“虚表”,它在编译期间就已经确定,在程序运行时就会被装载到.rodata,在整个程序运行期间都会一直存在。一个类实例化的多个对象,它们的虚函数指针指向的是同一张虚表,一个类拥有一张虚表  。下面是虚函数表的三个信息:

  • RTTI:run time type information 运行时类型信息
  • vfptr相对于内存布局的偏移
  • 虚函数入口地址

  以上Base类中虚函数指针vfptr指向的虚函数表——vftable如下所示

                                                                      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值