📜  在 C++ 中的基类中隐藏所有具有相同名称的重载方法

📅  最后修改于: 2022-05-13 01:54:19.276000             🧑  作者: Mango

在 C++ 中的基类中隐藏所有具有相同名称的重载方法

在 C++ 中,函数重载是可能的,即来自同一类的两个或多个函数可以具有相同的名称但不同的参数。但是,如果派生类重新定义了基类成员方法,那么所有同名的基类方法都将隐藏在派生类中。

例如,以下程序无法编译。在这里,Derived 重新定义了 Base 的方法 fun(),这使得 fun(int i) 隐藏。

CPP
// CPP Program to demonstrate derived class redefines base
// class member method and generates compiler error
#include 
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"; }
};
  
// Driver Code
int main()
{
    Derived d;
    d.fun(5); // Compiler Error
    return 0;
}


CPP
// CPP Program to demonstrate derived class redefines base
// class member method
#include 
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:
    // Makes Base::fun() and Base::fun(int )
    // hidden
    int fun(char c)
    {
        cout << "Derived::fun(char c) called";
    }
};
  
// Driver Code
int main()
{
    Derived d;
    d.fun('e'); // No Compiler Error
    return 0;
}


C++
// CPP Program to demonstrate derived class redefines base
// class member method using the 'using' keyword
#include 
using namespace std;
  
class Base {
public:
    int fun() { cout << "Base::fun() called"; }
};
  
class Derived : public Base {
public:
    using Base::fun;
  
    int fun(char c) // Makes Base::fun() and Base::fun(int )
                    // unhidden
    {
        cout << "Derived::fun(char c) called";
    }
};
  
// Driver Code
int main()
{
    Derived d;
    d.fun(); // Works fine now
    return 0;
}


输出

prog.cpp: In function ‘int main()’:
prog.cpp:20:12: error: no matching function for call to ‘Derived::fun(int)’
    d.fun(5); // Compiler Error
           ^
prog.cpp:13:9: note: candidate: int Derived::fun()
    int fun() { cout << "Derived::fun() called"; }
        ^
prog.cpp:13:9: note:   candidate expects 0 arguments, 1 provided

即使派生类方法的签名不同,基类中所有重载的方法都会被隐藏。例如,在下面的程序中,Derived::fun(char) 将 Base::fun() 和 Base::fun(int) 都隐藏起来。

CPP

// CPP Program to demonstrate derived class redefines base
// class member method
#include 
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:
    // Makes Base::fun() and Base::fun(int )
    // hidden
    int fun(char c)
    {
        cout << "Derived::fun(char c) called";
    }
};
  
// Driver Code
int main()
{
    Derived d;
    d.fun('e'); // No Compiler Error
    return 0;
}
输出
Derived::fun(char c) called

有一种方法可以缓解此类问题。如果我们想重载一个基类的函数,可以使用'using'关键字来取消隐藏它。此关键字将基类方法或变量带入当前类的范围。

C++

// CPP Program to demonstrate derived class redefines base
// class member method using the 'using' keyword
#include 
using namespace std;
  
class Base {
public:
    int fun() { cout << "Base::fun() called"; }
};
  
class Derived : public Base {
public:
    using Base::fun;
  
    int fun(char c) // Makes Base::fun() and Base::fun(int )
                    // unhidden
    {
        cout << "Derived::fun(char c) called";
    }
};
  
// Driver Code
int main()
{
    Derived d;
    d.fun(); // Works fine now
    return 0;
}
输出
Base::fun() called