3
  1. 第一个案例

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

完美运行。
程序输出
Write(int) 被调用

2.第二种情况。
只需将第一个函数移动到基类:

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

程序输出
Derived::Write(wchar_t) 被调用
但我预计“Base::Write(int) 被调用”
第二种情况有什么问题?

4

2 回答 2

4

你的编译器是对的。

在派生类中定义成员函数时,基类中同名的成员函数将被隐藏

您可以使用using将其导入派生类范围,使重载按预期工作。

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

编辑

函数重载不会通过不同的范围。当你调用Writeon 时,会在类作用域找到Derived名为的成员函数,然后停止名称查找,因此永远不会考虑in进行重载决策,即使基类版本在这里更合适。WriteDerivedWriteBase

请参阅名称查找

于 2016-02-13T15:02:51.147 回答
0

我猜这是因为程序找到了一个“较新”版本的函数,该函数在隐式转换中是正确的,所以它不会在父类中寻找一个“更好”的函数来调用。我建议:1)避免使用可互换的参数重载/重新定义函数。2)如果您真的希望调用 Derived::Write,请使用:

 p->Derived::Write(i);
于 2016-02-13T15:01:56.863 回答