C++多态实现原理

Posted Windows开发

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++多态实现原理相关的知识,希望对你有一定的参考价值。



多态是C++的一个重要特性,本文将深入介绍C++编译器是如何实现C++多态特性。

先看一段涉及多态的代码。

#include <iostream>using namespace std;
class BaseClass{public: virtual ~BaseClass() {}    virtual void VirtualFunction1()  cout << "I am base virtual function 1" << endl; }    virtual void VirtualFunction2()  cout << "I am base virtual function 2" << endl; }    void NonVirtualFunction()  cout << "I am base non virtual function" << endl; }private: int m_nBaseField = 0;};
class SubClass : public BaseClass {public: virtual ~SubClass() {}    virtual void VirtualFunction1() override  cout << "I am subclass function 1, override base class" << endl; }    void NonVirtualFunction()  cout << "I am subclass non virtual function" << endl; }private: int m_nSubClassField = 0;};
int main(){ BaseClass baseClass; SubClass subClass; BaseClass* pBaseClass = &baseClass; pBaseClass->VirtualFunction1(); pBaseClass = &subClass; pBaseClass->VirtualFunction1(); pBaseClass->NonVirtualFunction(); return 0;}

如上示例代码,定义基类BaseClass,BaseClass定义了虚析构函数、虚函数VirtualFunction1、虚函数VirtualFunction2、非虚函数NonVirtualFunction。

然后定义子类SubClass继承于BaseClass,覆盖重写BaseClass的虚析构函数、虚函数VirtualFunction1、函数NonVirtualFunction,未覆盖重写BaseClass的虚函数VirtualFunction2。

Main函数定义了两个对象baseClass和subClass,定义了BaseClass指针pBaseClass,先让pBaseClass指向baseClass对象,调用VirtualFunction1,然后让pBaseClass指向subClass,调用VirtualFunction1和NonVirtualFunction。

下面是输出结果:

从输出结果知:

第一,pBaseClass指向baseClass对象,调用VirtualFunction1时,是调用BaseClass::VirtualFunction1。当pBaseClass指向subClass对象,调用VirtualFunction1时,是调用SubClass::VirtualFunction1。也就是说,pBaseClass同样调用VirtualFunction1,但是会因为pBaseClass指向的对象不同,而产生不同的行为(调用不同的方法),这就是多态。

第二,pBaseClass指向subClass对象,调用NonVirtualFunction时,调用的是BaseClass::NonVirtualFunction,而不是SubClass::NonVirtualFunction。

 

接下来将重点解释下这两个结论,首先让我们看下baseClass和subClass这两个对象的内存布局。

C++多态实现原理

subClass继承于baseClass,内存布局上首先是baseClass的__vfptr和数据成员m_nBaseField,然后是SubClass定义的数据成员m_nSubClassField。subClass的__vfptr的值与baseClass的__vfptr的值不同,说明它们指向的虚函数表是不一样的。由于subClass没有新增虚函数,所以虚函数表也是三个元素与BaseClass的虚函数个数相同。但是,subClass覆盖重写了baseClass的虚析构函数和VirtualFunction1,所以第一和第二个元素的值不同,指向的是SubClass对应的虚函数。由于VirtualFunction2未被覆盖重写,所以第三个元素的值与BaseClass的虚函数表的第三个元素的值相同,都指向BaseClass::VirtualFunction2。

NonVirtualFunction不是虚函数,所以没有在虚函数表中。

 

接下来,我将结合虚函数表和汇编代码对上面的结论进行解释说明。

 

指针pBaseClass指向subClass对象,为什么调用VirtualFunction1方法时,是调用subClass::VirtualFunction1呢?让我们先看下汇编代码。

其次,读取eax所指向的内存的值放入寄存器edx,也就是pBaseClass->__vfptr的值(虚函数表指针的值)。

最后,call eax,也就是call VirtualFunction1。


以上是关于C++多态实现原理的主要内容,如果未能解决你的问题,请参考以下文章

C++静态多态与动态多态的实现原理剖析

C++静态多态与动态多态的实现原理剖析

9-3:C++多态之多态的实现原理之虚函数表,虚函数表指针静态绑定和动态绑定

C++多态 --- 多态实现原理简析

C++之多态总结(多态的定义及实现,抽象类,多态原理,单继承,多继承中的虚函数表)

[ C++ ] 多态原理 多态