运行时多态与编译时有什么不同

in what way runtime polymorphism differs from compile time

本文关键字:什么 多态 编译 运行时      更新时间:2023-10-16

这是一个运行时多态性的传统示例

#include<iostream>
using namespace std;
class Base {
public:
    virtual void show() { cout<<" In Base n"; }
    void show(int x) { cout<<"over loaded method base";}
};
class Derived: public Base {
public:
    void show() { cout<<"In Derived n"; } 
    void show(int x) { cout<<"over loaded method derived";}
};
int main(void) {   
    Base *bp = new Derived;
    Base *bp2=new Base;
    bp2->show(10); //Case 1: COMPILE-TIME POLYMORPHISM (overloading)
    bp->show();  //Case 2: RUN-TIME POLYMORPHISM (overriding)
    return 0;
}

//输出:重载方法base//导出

为什么在情形1中编译器可以理解调用哪个方法,而在情形2中却不能。对于编译器来说,派生类obj存储在bp中,而show是虚拟的,所以为什么它不能在编译时自己决定调用哪个show()呢?

为什么编译器可以理解在第1种情况下调用哪个方法,而在第2种情况下却不能理解

bp2->show(10);

解析为Base::show(int),因为它不是virtual函数。

bp->show(10);

也将解析为Base::show(int),即使bp指向Derived对象。

如果你希望调用指向Derived::show(int),则必须在Derived对象或指针上调用该函数。

Derived *dp = new Derived;
Base *bp = dp;
dp->show(10);   // Resolves to Derived::show(int)
bp->show(10);   // Resolves to Base::show(int)

至于在编译时解析调用哪个虚成员函数,编译器在某些情况下可以这样做。这取决于您使用的编译器和优化级别。然而,语言并不能保证这一点。

在编译时解析虚成员函数调用的一个相关问题:非final方法的非虚拟化

这解决了我的疑问NeilKirk和R Sahu的评论-

If it's non-virtual, it calls the function based on the type of the pointer. If it's virtual, it calls the function based on the actual type of object.

将被称为runtime