c – 为什么运行时多态性在编译时不能解决?

考虑:

#include<iostream>
using namespace std;

class Base
{
    public:
        virtual void show() { cout<<" In Base \n"; }
};

class Derived: public Base
{
    public:
       void show() { cout<<"In Derived \n"; }
};

int main(void)
{
    Base *bp = new Derived;
    bp->show();  // RUN-TIME POLYMORPHISM
    return 0;
}

为什么这段代码导致运行时多态性,为什么不能在编译时解决?

因为在一般情况下,在编译时不可能确定在运行时将是什么类型。您的示例可以在编译时解决(请参阅@Quentin的回答),但是可以构造不能的案例,例如:

Base *bp;
if (rand() % 10 < 5)
    bp = new Derived;
else
    bp = new Base;
bp->show(); // only known at run time

编辑:感谢@nwp,这里有一个更好的情况。就像是:

Base *bp;
char c;
std::cin >> c;
if (c == 'd')
    bp = new Derived;
else
    bp = new Base;
bp->show(); // only known at run time 

此外,由于推论Turing’s proof,可以表明在一般情况下,C编译器在数学上不可能知道基类指针在运行时指向什么。

假设我们有一个类似C编译器的函数:

bool bp_points_to_base(const string& program_file);

这需要输入program_file:任何C源代码文本文件的名称,其中指针bp(如在OP中)调用其虚拟成员函数show()。并且在一般情况下(在序列点A处,其中虚拟成员函数show()首先通过bp被调用):指针bp是否指向Base的实例。

考虑下面的C程序“q.cpp”的片段:

Base *bp;
if (bp_points_to_base("q.cpp")) // invokes bp_points_to_base on itself
    bp = new Derived;
else
    bp = new Base;
bp->show();  // sequence point A

现在如果bp_points_to_base确定在“q.cpp”中:bp指向A的Base的实例,则“q.cpp”将bp指向在A的其他位置。如果它在“q.cpp”中确定:bp doesn’ t指向Base在A的实例,则“q.cpp”将bp指向Base处的A实例。这是一个矛盾。所以我们的初步假设是不正确的。所以bp_points_to_base不能写成一般情况。

http://stackoverflow.com/questions/34354516/why-cant-run-time-polymorphism-be-solved-at-compile-time

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c – 为什么运行时多态性在编译时不能解决?