C++虚函数作用原理(一)——虚函数如何在C++语言逻辑中存在

C++多态,接触其实也没太长的时间。上课的时候老师总是不停的讲,多态可以实现利用一个基类对象调用不同继承类的成员函数。我就会觉得很伤脑筋,这个的原理到底是什么?是什么呢?
开始的时候我觉得自己应该能够把它的原理想出来,因为一直觉得关于这些高级语言的事情,不论看起来多么神奇,其实应该都是之前学的基础累积起来的。所以,我就自己想了一段时间————能够实现这样效果的只有 **指针** 了。
但是这个指针应该怎么定义呢?就算基类中本身定义了一个指针,可是继承类中被继承来的函数在利用基类的时候怎么告诉基类到底调用哪一个继承类的函数呢?真的伤脑筋。
……
现在是开始这个博客的第二天,我终于可以开始继续写了——因为我开始自己调试观察虚函数。
OK,现在开始了:
首先:

一、没有继承的类

(1)段小小的代码:

class A
{
	int x;
	int y;
public:
	virtual void out()
	{
		cout << x << y << endl;
                cout<<"A"<<endl;
	}
};
int main()
{
	A a;
	return 0;
}
十分明显这段程序中仅仅只有一个类,一个虚函数!现在我们一起来看看类A的成员到底如何分布的。


成员变量xy存在。同时出现了 _vptr 。它是什么?没错儿就是虚函数表指针。也就是说这个_vptr就是指向虚函数表(或者理解它为指向,存有所有虚函数地址的一个数组的指针)的一个指针!
现在我们点开_vptr发现:

它里面仍然是一个指针但是这个是指向我们唯一的虚函数void out()的指针!

总结:

通过上面的观察,我们知道了虚函数是由虚函数表里面存储的地址通过寻址的方式来实现的。那么就意味着我们可以直接通过地址来调用函数!这里我们也可以通过一段代码验证我所述的是否为真。

首先我们要获得虚函数表指针:

int main()
{
	A a;
	int *_Avptr;
	_Avptr = (int *)&a;//获得虚函数表指针,并通过强制转化为(int*)型。

	return 0;
}

获得虚函数指针

int main()
{
	A a;
	int *_Avptr;
	int *Varr;
	_Avptr = (int *)&a;//获得虚函数表指针,并通过强制转化为int*型。
	Varr = (int *)*(_Avptr);//获得虚函数指针。
	return 0;
}

直接通过指针调用函数

```typedef void(*pFUNC)(void);//定义一个无返回值,无参数的指针型函数。 ``` ``` int main() { A a; int *_Avptr; int *Varr; _Avptr = (int *)&a;//获得虚函数表指针,并通过强制转化为int型。 Varr = (int *)*(_Avptr);//获得虚函数指针。
pFUNC pfunc1 = (pFUNC)*Varr;//开始利用地址直接访问虚函数
pfunc1();
return 0;

}

###运行结果:
![](https://img2018.cnblogs.com/blog/1784621/201911/1784621-20191112185538732-616549306.png)

virtual void out()
{
cout << x << y << endl;
cout<<"A"<<endl;
}

输出内容和我们虚函数中写的函数需要我们输出的无异议。所以证明了我们之前的想法。
现在,对虚函数到底是怎么存在的应该没有什么问题了。
posted @ 2019-11-12 19:04  lisui  阅读(403)  评论(0编辑  收藏  举报