调用虚函数时的奇怪行为

调用虚函数时的奇怪行为

本文介绍了调用虚函数时的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白这段代码有什么问题.它看起来像一个不可思议的陷阱!

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; }
};

这篇关于调用虚函数时的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 17:16