2016-02-13 85 views
3
  1. 第一种情况为什么C++编译器(VS2013)选择错误的函数?

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

完美。
程序输出
写入(INT)被称为

2.Second情况。
刚搬进去功能基类:

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

计划的成果
衍生::写(wchar_t的)被称为
但我希望 “基地::写(INT)被称为”
第二种情况有什么问题?

+1

@hvd:我认为这是一个重复的,但不是[这个问题](http://stackoverflow.com/questions/9991143/virtual-functions-overriding-and-hiding?lq= 1)。 –

+0

@ hvd:这个问题通过派生类型的指针进行查找,即通过基类型进行查找。这个问题在不同范围内介绍了这些函数,我们在基类中介绍了它们。另一个问题似乎完全是关于虚拟调度如何被称为最衍生的调度,而与隐藏完全没有任何关系。 –

+0

@ hvd:或者,也许另一个问题首先将“坏”(有趣)的行为。在这种情况下,这个问题实际上调用了更多派生类中的重载,该问题调用了基类中的那个。在其他问题中,名称隐藏并不在其中。 –

回答

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

EDIT

函数重载不会通过不同的范围。当您在Derived打电话Write,命名为Write成员函数将在Derived类范围中找到,然后名称查找将停止,所以在BaseWrite永远即使基类被视为重载解析,版本在这里更合适。

Name lookup

+0

但函数有不同的参数类型。为什么写(wchar_t)隐藏写(int)?这是正确的? – Alex

+0

@Alex请参阅我编辑的答案。这是正确的行为。 – songyuanyao

+0

感谢您的详细解释。 – Alex

0

我想这是因为程序找到了一个“更新”版本的功能,这是隐式转换正确的,所以它不寻找一个“更好”的函数来调用父类。 我建议: 1)避免使用可互换的参数来重载/重新定义函数。 2)如果你真的想派生::写被调用,使用:

p->Derived::Write(i);