【复习】C++之虚函数与多态

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ddiioopp123/article/details/88667168

C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。

对C++了解的人都应该知道虚函数是通过一张虚函数表来实现的。在这个表中,主要是一个类的虚函数地址表,虚拟函数表是在编译时期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组,而对象的隐藏成员,虚拟函数表指针是在运行时期,也就是构造函数被调用时进行初始化的,这时实现多态的关键。

在C++的标准规格说明书中说道,编译器必须要保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证正确取到虚函数的偏移量)。这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。

多态是基于虚函数完成,虚函数基于重写。

Q:虚函数怎么实现多态原理?

通过维护一个虚函数列表v_table,虚函数列表的每个元素是一个函数指针,指向一个虚函数,或者子类重写函数。需要vfptr记录这个类所使用那个虚函数列表,之后 要用父类的指针调用虚函数,通过vfptr找到v_table列表中的函数调用。

v_table虚函数列表在编译期创建,vfptr指向表的指针在创建对象的指针时存在,是父类中的第一个数据成员,并且在构造函数里的初始化指向自己类中。

虚函数实现多态的优点:复用,扩展。

虚函数实现多态的缺点:虚函数列表的空间,效率,安全性。

Q:哪些函数需要使用虚函数,什么时候实现多态?

如果父类的指针指向子类的对象,需要使用子类的东西都要是虚函数的。

Q:什么时候出现父类的指针指向子类的对象?

把不同的类型统一成同一个种类。

关于安全性

通过父类型的指针访问子类自己的虚函数,任何妄图使用父类指针想调用子类中未覆盖父类的成员函数的行为都会被编译器视为非法。但在运行时可以通过指针的方式访问虚函数列表来达到目的。

另外,如果父类的虚函数是private或是protected的,但这些非public的虚函数同样会存在于虚函数列表中,所以我们同样可以使用访问虚函数列表的方式来访问这些non-public的虚函数。

猜你喜欢

转载自blog.csdn.net/ddiioopp123/article/details/88667168