3
  1. First case

    #include <iostream>
    class A
    {
    public:
        virtual void Write(int i)
        {
            std::wcout << L"Write(int) is called" << std::endl;
        }
        virtual void Write(wchar_t c)
        {
            std::wcout << L"Write(wchar_t) is called" << std::endl;
        }
    };
    int _tmain(int argc, wchar_t* argv[])
    {
        A *p = new A();
        int i = 100;
        p->Write(i);
        return 0;
    }
    

Works perfectly.
Program outputs
Write(int) is called

2.Second case.
Just move first function to base class:

#include <iostream>
class Base
{
public:
   virtual void Write(int i)
   {
       std::wcout << L"Base::Write(int) is called" << std::endl;
   }
};
class Derived: public Base
{
public:
    virtual void Write(wchar_t c)
    {
        std::wcout << L"Derived::Write(wchar_t) is called" << std::endl;
    }
};
int _tmain(int argc, wchar_t* argv[])
{
    Derived *p = new Derived();
    int i = 100;
    p->Write(i);
    return 0;
}

Program outputs
Derived::Write(wchar_t) is called
But I expected "Base::Write(int) is called"
What is wrong in second case?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Alex
  • 33
  • 3
  • 1
    @hvd: I think it's a duplicate, but not of [that question](http://stackoverflow.com/questions/9991143/virtual-functions-overriding-and-hiding?lq=1). – Ben Voigt Feb 13 '16 at 15:29
  • @hvd: This question does lookup through a pointer of derived type, that one through base type. This question introduces the functions in different scopes, that one introduces them both in the base class. That other question appears to be solely about how virtual dispatch call the most-derived overridder, and has nothing at all to do with hiding. – Ben Voigt Feb 13 '16 at 15:37
  • @hvd: Or maybe the other question puts the "bad" (interesting) behavior first. In which case, this question actually calls the overload in the more derived class, that question calls the one in the base class. Name hiding is not at play in the other question at all. – Ben Voigt Feb 13 '16 at 15:40
  • @BenVoigt That's convincing enough, thanks. A quick search brings up [C++ inheritance and name hiding](http://stackoverflow.com/questions/32946364/c-inheritance-and-name-hiding) and [C++ inheritance, base methods hidden](http://stackoverflow.com/questions/3823287/c-inheritance-base-methods-hidden) as possible better duplicate candidates. –  Feb 13 '16 at 15:40

2 Answers2

4

Your compiler is right.

When you define member function in derived class, the member function with same name in base class will be hidden.

You can use using to import it into the derived class scope, make the overloading work as you expect.

class Derived: public Base
{
public:
    using Base::Write;
    virtual void Write(wchar_t c)
    {
        std::wcout << L"Derived::Write(wchar_t) is called" << std::endl;
    }
};

EDIT

Function overloading won't pass through different scopes. When you call Write on Derived, the member function named Write will be found at the Derived class scope, and then name lookup will stop, so the Write in Base will never be considered for overload resolution, even if the base class version is more appropriate here.

See Name lookup

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
0

I guess it's because the programm finds a "newer" version of the function which is correct with implicit conversion, so it doesn't look for a "better" function to call in parent class. I'd suggest : 1) avoid overloading/redefining functions with parameters that are interchangeable. 2) If you REALLY want Derived::Write to be called, use :

 p->Derived::Write(i);
bisthebis
  • 523
  • 2
  • 10