刚从网上看点C++东东写的不错。在此,结合自己所理解地,整理整理C++中重载(overload), 覆盖(override)和隐藏概念。
- 重载(overload)指函数名相同,但是它的参数表列个数或顺序,类型不同。但是不能靠返回类型来判断。
- 其特征为:
- 相同的范围(在同一个作用域中) ;
- 函数名字相同;
- 参数不同;
- virtual 关键字可有可无。
- 返回值可以不同;
- 重写(也称为覆盖 override)是指派生类重新定义基类的虚函数,
- 特征是:
- 不在同一个作用域(分别位于派生类与基类) ;
- 函数名字相同;
- 参数相同;
- 基类函数必须有 virtual 关键字,不能有 static 。
- 返回值相同(或是协变),否则报错;
- 重写函数的访问修饰符可以不同。尽管 virtual 是 private 的,派生类中重写改写为 public,protected 也是可以的。
- 重定义(也成隐藏)
- 特征是:
- 不在同一个作用域(分别位于派生类与基类) ;
- 函数名字相同;
- 返回值可以不同;
- 参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意与重载以及覆盖混淆) 。
- 参数相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意与覆盖混淆) 。
给参考代码,便于理解
// Eclipse CDT and G++
#include <iostream>
#include <complex>
using namespace std;
class Base
{
public:
virtual void f(int){
cout<<"Base::f(int)"<<endl;
}
virtual void f(double){
cout<<"Base::f(double)"<<endl;
}
virtual void g(int){
cout<<"Base::g(int)"<<endl;
}
void h(int x){
cout<<"Base::h(int)"<<endl;
}
};
class Derived : public Base
{
public:
// redefine the Base::f() function
void f(complex<double>){
cout << "Derived::f(complex<double>)" << endl;
}
// override the Base::g(int) function
void g(int x){
cout << "Derived::g(int)" << endl;
}
// redefine the Base::h() function
void h(int){
cout << "Derived::h(int)" << endl;
}
};
int main()
{
Base base;
Derived derived;
Base* pb = new Derived;
base.f(1.0); // Base::f(double)
derived.f(1.0); // Derived::f(complex)
pb->f(1.0); // Base::f(double), This is redefine the Base::f() function
base.g(10); // Base::g(int)
derived.g(10); // Derived::g(int)
pb->g(10); // Derived::g(int), This is the virtual function
delete pb;
return 0;
}
输出结果:
Base::f(double)
Derived::f(complex<double>)
Base::f(double)
Base::g(int)
Derived::g(int)
Derived::g(int)
通过上述的代码和输出结果,不难可以看出,
- 第一、Base类中的第二个函数f是对第一个的重载;
- 第二、Derived类中的函数g是对Base类中函数g的重写,即使用了虚函数特性。
- 第三、Derived类中的函数f是对Base泪中函数f的隐藏,即重定义了。
- 第四、pb指针是一个指向Base类型的指针,但是实际指向了一个Derived的空间,这里对pd调用函数的处理(多态性)取决于是否重写(虚函数特性)了函数,若没有,则依然调用基类。
- 第五、只有在通过基类指针或基类引用 间接指向派生类类型时多态性才会起作用。因Base类的函数h没有定义为virtual虚函数,所以Derived类的函数h是对Base::h()的重定义。
关于程序设计基石与实践更多讨论与交流,敬请关注本博客和新浪微博songzi_tea.