问题描述
我不明白这段代码有什么问题.它看起来像一个不可思议的陷阱!
I don't understand what is wrong with this code. It looks like an incredible trap !
此代码:
class Foo
{
public:
virtual double foo(double x) const = 0;
double foo(int x) const { return (double)(x + x); }
};
class Bar : public Foo
{
public:
virtual double foo(double x) const { return x * x; }
};
int main()
{
Bar* b = new Bar;
Foo* f = b;
std::cout << b->foo(3) << " " << f->foo(3) << std::endl;
std::cout << b->foo(5.0) << " " << f->foo(5.0) << std::endl;
return 0;
}
打印以下输出:
9 6
25 25
我推断当指针的类型是 Bar*
时,Bar::foo(double) const
被隐式转换调用.但是为什么在没有任何警告的情况下会发生这样的事情?
I deduce that Bar::foo(double) const
is called with an implicit cast when the type of the pointer is Bar*
. But why such a thing is possible without any warning ?
我使用 GCC 4.7.2.我用 g++ -Wall foobar.cpp -o foobar.exe
I work with GCC 4.7.2. I compiled with g++ -Wall foobar.cpp -o foobar.exe
推荐答案
这是由于名称隐藏造成的.
This is due to name hiding.
当你在 Bar
中声明一个名为 foo
的函数时,你会在 Foo
中隐藏所有同名的声明.
When you declare a function called foo
in Bar
, you hide all declarations with the same name in Foo
.
因此,当指针的静态类型为 Bar
时,编译器只在 Bar
中找到带有 的版本>double
,所以它隐式转换了 int
来满足这一点.
As such, when the static type of the pointer is Bar
, the compiler only finds the version in Bar
which takes a double
, so it implicitly converts the int
to satisfy this.
如果您希望 Foo
中的 int
版本可见,请添加一个 using
声明:
If you want the int
version in Foo
to be visible, add a using
declaration:
class Bar : public Foo
{
public:
using Foo::foo;
// ^^ makes the versions in Foo visible
virtual double foo(double x) const { return x * x; }
};
这篇关于调用虚函数时的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!