我试图在C ++中试验运行时多态性。有人能解释一下这个程序的输出吗?我跑了它,它给了我一个Derived的输出(意思是,派生类的函数f()被调用)。
此外,如果我取消注释语句,该程序的预期行为是什么 - d.f(); ?
// Example program
#include <iostream>
#include <string>
class Base {
public :virtual void f(int a = 7){std::cout << "Base" <<std::endl;}
};
class Derived : public Base {
public :virtual void f(int a) {std::cout << "Derived" <<std::endl;}
};
int main() {
Derived d;
Base& b = d;
b.f();
//d.f();
return 0;
}
答案 0 :(得分:1)
默认参数在编译时解析。所以对于编译器,你正在做b.f(7);
由于f是虚拟的,而实际的b是Derived,所以派生的f()在运行时被调用,因为运行时将查找对象的vTable,并且它将找到派生的f()。 / p>
此外,如果我取消注释,该程序的预期行为是什么 声明 - d.f(); ?
我期待编译器错误,因为编译器会查找Derived :: f并且那里没有默认参数。
答案 1 :(得分:0)
当您在对象上调用函数时,必须在编译时找到该函数。在运行时,调用的实际函数取决于运行时调度机制。
在您的情况下,通话
b.f();
在编译时解析为Base::f(int)
,并将a
的值设置为参数的默认值。
电话
d.f();
将无法编译。该函数已解析为Derived::f(int)
。但是,由于Derived::f(int)
没有参数的默认值,因此在调用时必须提供一个值。
d.f(10);
会奏效。
在运行时,该调用已解析为Derived::f(int)
,因为没有其他实现覆盖它。