c++inheritancemember-functionsname-lookupname-hiding

Why c++ compiler (VS2013) chooses wrong function?


  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?


Solution

  • 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