考虑:
#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
:any C++ 源代码文本文件的名称,其中指针 bp
(如在 OP ) 调用它的 virtual
成员函数 show()
。并且可以确定在一般情况下(在virtual
成员函数show()
首先出现的序列点A
通过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
实例code> 然后 "q.cpp"将 bp
指向 A
处的其他内容。如果它确定在“q.cpp”中:bp
没有指向 A
处的 Base
实例,那么“q. cpp"将 bp
指向 A
处的 Base
实例。这是一个矛盾。所以我们最初的假设是不正确的。所以bp_points_to_base
不能写成一般情况。
关于c++ - 为什么不能在编译时解决运行时多态性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34354516/