3

最近我开始知道这一点 - 如果派生类重新定义基类成员方法,那么所有具有相同名称的基类方法都会隐藏在派生类中。

#include<iostream>

using namespace std;

class Base
{
public:
int fun()
{
    cout<<"Base::fun() called";
}
int fun(int i)
{
    cout<<"Base::fun(int i) called";
}
};

class Derived: public Base
{
public:
int fun() 
{
    cout<<"Derived::fun() called";
}
};

int main()
{
Derived d;
d.fun(5);  // Compiler Error
return 0;
}

错误:在函数“int main()”中:第 30 行:错误:没有匹配函数调用“Derived::fun(int)”编译由于 -Wfatal 错误而终止。

但只想知道背后的原因?为什么它不调用基类的 fun(int i) 方法,因为派生类是从基类派生的

4

2 回答 2

5

根本原因是为了让代码更健壮。

struct Base {
};

struct Derived : Base {
    void f(long);
    void g() { f(3); } // calls Derived::f
}

现在假设Base在一个库中定义,并且您获得了对该库的更新,并且更新更改了以下定义Base

struct Base {
    void f(int);
};

现在假设在找到名称时搜索重载函数并没有停止。在这种情况下,Derived::g将调用Base::f而不是Derived::f,并且您的派生类将悄悄地做一些与以前完全不同的事情,也不同于它的设计和记录要做的事情。

于 2013-04-08T13:59:57.693 回答
2

您已经发现派生类重载会以相同的名称但不同的参数隐藏(阻止其可见性)基类方法。让我们声称这是出于某种历史或感知的安全原因,并查看修复:

class Derived: public Base
{
public:
  using Base::fun; // expose the base-class method
  int fun() 
  {
    cout<<"Derived::fun() called";
  }
};
于 2013-04-08T13:55:40.023 回答