隐藏基类中的所有重载方法

Hiding of all overloaded methods in base class

本文关键字:重载 方法 基类 隐藏      更新时间:2023-10-16

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

#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-errors导致编译终止。

只是想知道背后的原因吗?既然派生类是从Base

派生的,为什么不调用基类的fun(int i)方法呢?

最根本的原因是为了使代码更健壮。

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,并且您的派生类将悄悄地做一些与之前所做的完全不同的事情,并且与设计和文档所做的完全不同。

您已经发现派生类重载将通过相同的名称但不同的参数遮蔽(防止可见)基类方法。让我们假设这是出于历史原因或安全原因,并查看修复方法:

class Derived: public Base
{
public:
  using Base::fun; // expose the base-class method
  int fun() 
  {
    cout<<"Derived::fun() called";
  }
};