C++虚函数、虚函数表、多态的深入理解

C++虚函数、虚函数表、多态的深入理解

大家都知道多态发生需要:

  • 要有继承
  • 要有虚函数重写
  • 父类指针指向子类对象

那么c++底层是如何实现多态这个骚操作的呢,接下来我谈谈自己的看法:

首先定义两个类:

class fruit {
public:
	int f;
	fruit(int fi) { f = fi; };
	virtual void show() {
		cout << "I am fruit" << endl;
	}
};

class apple : public fruit {
public:
	apple(int i) : fruit(i) {};
	virtual void show() {
		cout << "I am apple" << endl;
	}
};

我们定义两个类的对象:

int main() {
	fruit f1(1);
	apple a(2);
	system("pause");
	return 0;
}

他们的实际内存模型是这样的:
在这里插入图片描述
对象f1和对象a的内存模型中会有一个指向虚函数表的指针,就是一个4字节内存块(32位平台下),指针指向一块内存,该内存块中存储的就是函数指针。不进行虚函数重写,那么对象a的虚函数表就和对象f一样,但如果进行了重写,虚函数表中的函数指针指向的就是对象a自己实现的show()函数。

接下来验证底层是否是这样实现的:

用visio studio观察对象:
在这里插入图片描述
可以看到对象中确实多了_Vfptr的变量,它就是指向虚函数表的指针。那么虚函数表中的指针是否就是指向对象a中show()的函数呢?考虑以下代码:

typedef void(*func)();  // 函数指针类型 别名func

int main() {
	fruit f1(1);
	apple a(2);


	fruit* f2 = &a;
	f2->show();   // 多态的使用
	
	// 底层实现模拟  类似把上面的函数调用翻译成下面的实现
	int* p = (int*)(&a);  // 取出虚函数表指针
    cout << hex << *p << endl;
	func pf = (func)*((int*)(*p));  // 函数指针
	//func pf = (func)(((int64_t*)(*p))[0]); // 等效为上一句
	cout << hex << *pf << endl; 
	pf();  // 执行函数  效果和f2->show()一样

	system("pause");
	return 0;
}

在这里插入图片描述

当执行f2->show()时,取出了对象a的虚函数表然后根据调用的函数执行相应的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值