CPP拾遗
Qianming Huang Three

多态

动态多态是基于虚函数的。没有虚函数,就没有动态多态。

多态的具体实现是由编译器在编译的时候实现的,所以被称为动态多态。伪代码如下:

1
2
3
4
A()
{
vptr = &A::vftable;
}
  • 问题1:多态的具体形式。

    答案:父类指针指向子类对象,或者对子类对象的引用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class Base
    {
    public:
    virtual void myvirfunc() {}
    };

    int main()
    {
    Base* pa = new Base();
    pa->myvirfunc(); // 多态

    Base base;
    base.myvirfunc();// 不是多态

    Base* ybase = &base;
    ybase->myvirfunc();// 多态

    return 0;
    }

    base.myvirfunc()不是多态的原因在于,其对应的汇编代码如下:

    1
    2
    3
    00007FF6DB741BDC  lea         rcx,[base]  
    00007FF6DB741BE0 call Base::myvirfunc (07FF6DB741073h)
    00007FF6DB741BE5 nop

    这里的调用是硬编码的,意味着编译时已经确定调用哪个函数。而ybase->myvirfunc();的汇编代码如下:

    1
    2
    3
    4
    5
    00007FF6DB741BEE  mov         rax,qword ptr [ybase]  
    00007FF6DB741BF2 mov rax,qword ptr [rax]
    00007FF6DB741BF5 mov rcx,qword ptr [ybase]
    00007FF6DB741BF9 call qword ptr [rax]
    00007FF6DB741BFB nop

    这里是在动态的链接,调用的是vptr指向的虚函数表。