【发布时间】:2015-07-21 22:38:07
【问题描述】:
这个例子展示了一个派生类对象被传递给一个函数,该函数将基类的引用作为参数。派生类中的成员函数g(int) 隐藏了基类中的g(float)。我明白这一点,我的问题与此无关。
class Base {
public:
virtual void g(float x) throw()
{
cout << "Base::g(float)\n";
}
};
class Derived : public Base {
public:
virtual void g(int x) throw() // Bad: Hides Base::g(float)
{
cout << "Derived::g(int)\n";
}
};
void sampleTwo(Base& b, Derived& d)
{
b.g(3.14f);
d.g(3.14f); // Bad: Converts 3.14 to 3 and calls Derived::g(int)
}
int main()
{
Derived d;
sampleTwo(d, d);
return 0;
}
输出是:
Base::g(float)
Derived::g(int)
我的问题是输出“Base::g(float)”。由于sampleTwo()中'b'引用的对象是派生对象,难道动态绑定不应该调用派生类的g()方法(将float转为int)吗?
【问题讨论】:
-
在编写派生类的函数来覆盖基类的虚函数时,最好开始使用
override关键字(假设编译器具有合理的 C++11 支持)。这样,如果函数实际上没有按照您的预期覆盖,编译器就会给您一个错误。 -
我也很惊讶,但我最初的猜测是看到 base::g(float) 调用了两次,而不是 derived::g(int),因为这两种情况下的函数调用都匹配g(float) 的签名,它是与 g(int) 不同的函数(这是两个不同的函数,您的代码不会进行任何覆盖)
-
您应该在
Derived中执行using Base::g以取消隐藏Base::g(float)。
标签: c++ dynamic-binding