C++之多态原理

首先可以确定的是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指针的值了。

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

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

扫描二维码关注公众号,回复: 10508328 查看本文章

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

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

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

 

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

 

 

 

 

 

 

 

 

 

发布了222 篇原创文章 · 获赞 174 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/zy010101/article/details/105283049
今日推荐