Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behaviour when calling virtual functions

Tags:

c++

virtual

I don't understand what is wrong with this code. It looks like an incredible trap !

This code :

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

prints the following output :

9 6
25 25

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 ?

I work with GCC 4.7.2. I compiled with g++ -Wall foobar.cpp -o foobar.exe

like image 501
Caduchon Avatar asked Jun 10 '15 08:06

Caduchon


1 Answers

This is due to name hiding.

When you declare a function called foo in Bar, you hide all declarations with the same name in Foo.

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.

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; }
};
like image 113
TartanLlama Avatar answered Sep 29 '22 20:09

TartanLlama