在 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
Note: The above facts are true for both static and non static methods.
有一种方法可以缓解此类问题。如果我们想重载一个基类的函数,可以使用'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