前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++之多态原理

C++之多态原理

作者头像
zy010101
发布2020-04-08 16:50:25
3760
发布2020-04-08 16:50:25
举报
文章被收录于专栏:程序员程序员

首先可以确定的是virtual关键字会传递给C++编译器一个重要信息,那就是这个函数是一个虚函数,需要特殊处理。

C++编译器到底设计了一种什么样的方案来实现的?

编译器的设计者就想了个巧妙的办法,弄一张虚函数表来存放虚函数的入口地址(函数指针)。然后在类中弄一个隐藏的指针变量指向这张虚函数表。

我们可以来测试一下,下面这个类是不带任何属性成员的,但是它有一个虚函数。在x86平台下测试。

#include<iostream>

using namespace std;

class Parent
{
public:
	virtual void fun(){cout << "Hello World!" << endl;}
};


int main()
{
        Parent parent;
	cout << sizeof(parent) << endl;

	return 0;
}

可以看的这个类果然占据了4字节。32为下指针刚好是4字节。

既然有个指针指向了这个虚表,虽然我们无法通过成员运算符拿到该指针。它不像this一样 ,我们可以直接拿到。经过查阅资料发现对象空间的最开始四字节内容,就是虚表(虚函数列表)的地址。这样我们就拿到了vptr指针的值了。

下面我们就用指针去取这个地址。

这么做了之后,将其赋值给一个函数指针。

这样我们就能通过p来调用第一个虚函数。

下面我们来看看虚指针到底是怎么实现动态调用函数的呢?

很明显,当我们传递一个父类的地址给父类指针,那么父类的vptr被初始化。这时候就回去父类的虚函数表中寻找相应的函数;而当我们传递一个子类的地址给父类指针,那么子类的vptr被初始化,这时候就在子类的虚表中寻找相应的函数。

需要注意的是,vptr指针其实也是被构造函数给初始化的。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档