【问题标题】:in what way runtime polymorphism differs from compile time运行时多态性与编译时有何不同
【发布时间】:2015-09-22 21:05:36
【问题描述】:

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

#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;
}

//输出:重载方法库 // 在派生中

为什么编译器可以理解在编译时调用哪个方法在案例 1 中而不是在案例 2 中。 在案例 2 中——因为编译器很清楚派生类 obj 存储在 bp 中并且 show 是虚拟的,所以为什么它不能决定在编译时调用哪个 show()。

【问题讨论】:

  • 您的示例中没有编译时多态性(与模板相关)。您通过show() 的虚函数具有常规多态性,并且您在show(int) 的派生类中隐藏了基类中的函数。
  • 在这个例子中很明显bp指向一个Derived对象,但是如果指针是一个参数呢?编译器应该看多远才能看到真正分配的类型?这将使 C++ 编译器比现在更慢。所以规则允许它在这种情况下是短视的,当调用非虚函数时。
  • @bku_drytt 有编译时间 poly.. 因为 bp2 用于调用 show(10)。请再次检查代码。它不是功能隐藏
  • @NeilKirk 是这样的吗?如果编译器看到相同类型的对象存储在相同类型的变量中,它会在编译时决定,如果其他类型的 obj 存储在其他变量中,它会将这个决定推迟到运行时???
  • 如果是非虚拟的,则根据指针的类型调用函数。如果是虚拟的,则根据对象的实际类型调用函数。

标签: c++ polymorphism runtime virtual overriding


【解决方案1】:

为什么编译器可以在情况 1 中而不是在情况 2 中了解在编译期间调用哪个方法

bp2->show(10);

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

bp->show(10);

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

如果您希望将调用定向到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)

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

编译时解析虚成员函数调用的相关问题:Devirtualizing a non-final method

【讨论】:

  • 你知道什么是函数覆盖吗?我也叫 bp->show() 而不是 bp->show(10) 两者都不同第一个是虚拟的
  • @SaurabhKumar,我不是在谈论我的回答中的虚拟成员函数。我试图向您解释如何解决对非虚拟成员的调用。
  • 是的,但我的问题是为什么虚函数调用不能在编译时本身解决
  • @SaurabhKumar,在某些情况下可以。这取决于您使用的编译器和优化级别。但是,语言不保证这一点。
  • 与你关于虚成员函数的问题有关:stackoverflow.com/questions/32720642/…
【解决方案2】:

这解决了我对 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.

这将被称为运行时

【讨论】:

    猜你喜欢
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多