此示例显示了传递给函数的派生类对象,该函数将基类作为参数引用。派生类中的成员函数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)
我的问题是输出&#34; Base :: g(float)&#34;。由于&#39; b&#39;引用的对象在sampleTwo()中是派生对象,不应该动态绑定调用派生类的g()方法(将float转换为int)?
答案 0 :(得分:3)
g(int)
和g(float)
是两种完全不同的方法。 Derived::g(int)
不会覆盖Base::g(float)
。这些方法无关。
由于Derived
未覆盖g(float)
,因此您对b.g(3.14f)
的期望是没有根据的。正如所料,b.g(3.14f)
应致电Base::g(float)
。
如果您在g(float)
中覆盖Derived
,则b.g(3.14f)
确实会致电Derived::g(float)
。
答案 1 :(得分:1)
动态调度会调用最终的覆盖。由于Derived::g
隐藏而不是覆盖Base::g
,Base::g
中Derived
的最终覆盖仍为Base::g
。
答案 2 :(得分:0)
g(float)
和g(int)
是不同的功能成员。如果您希望Derived
起作用,则必须在两个类中使用g(float)
。
g()
可以重载检出函数重载:
https://en.wikipedia.org/wiki/Function_overloading
示例(g(float)
和g(int)
在同一个类和单独的函数中):
class Derived : public Base {
public:
void g(float x) throw();
void g(int x) throw();
};