关于c ++:隐藏基类中所有重载的方法

Hiding of all overloaded methods in base class

最近我才知道这一点——如果派生类重新定义了基类成员方法,那么所有同名的基类方法都将隐藏在派生类中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#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)方法,因为派生类是从基派生的


根本原因是使代码更加健壮。

1
2
3
4
5
6
7
struct Base {
};

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

现在假设Base是在库中定义的,您将得到该库的更新,更新将更改Base的定义:

1
2
3
struct Base {
    void f(int);
};

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


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

1
2
3
4
5
6
7
8
9
class Derived: public Base
{
public:
  using Base::fun; // expose the base-class method
  int fun()
  {
    cout<<"Derived::fun() called";
  }
};