函数的重载(overload)
在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数。
示例如下:
#include <iostream>
using namespace std;
class printData
{
public:
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double f) {
cout << "浮点数为: " << f << endl;
}
void print(char c[]) {
cout << "字符串为: " << c << endl;
}
};
int main(void)
{
printData pd;
// 输出整数
pd.print(5);
// 输出浮点数
pd.print(500.263);
// 输出字符串
char c[] = "Hello C++";
pd.print(c);
return 0;
}
由此,我们也可以自定义重载运算符。
函数的重写(override也叫覆盖)
当父类中的函数的功能不满足子类的的需求时,就需要重写。子类重新定义父类中有相同名称和参数的虚函数。函数特征相同,但是具体实现不同。因此子函数将其父类中的对应函数覆盖。
重写需要注意:
1 被重写的函数不能是static的。必须是virtual的,有virtual关键字!
2 重写函数必须有相同的类型,名称和参数列表。
3 重写函数的访问修饰符可以不同。尽管virtual是private的,派生类中重写改写为public,protected也是可以的
#include<iostream>
using namespace std;
class A {
virtual let(){
cout<<"I'm A"<<endl;
}
};
class B:public A {
public :let(){
cout<<"I'm b"<<endl;
}
};
int main(void)
{
A a; //很简单,定义a的时候调用了一次构造函数
B b;
b.let();
}
函数的重定义(redefining也叫隐藏)
指子类重新定义父类中的非虚函数(参数列表可以不同),这样父类中的对应函数将被隐藏。如果一个类,存在和父类相同的函数,那么,这个类将会覆盖其父类的方法,除非你在调用的时候,强制转换为父类类型,否则试图对子类和父类做类似重载的调用是不能成功的。
派生类的函数屏蔽了与其同名的基类函数,规则是:
a、若派生类的函数和基类的函数同名,但参数不同,此时不管有无virtual,基类的函数被隐藏
b、若派生类的函数和基类的函数同名,且参数相同,但基类没有virtual关键字,基类的函数被隐藏
区别
重写(override)与重载(overload)的区别
1、函数重写是子类和父类之间的继承关系,是垂直关系;方法的重载是同一个类中方法之间的关系,是水平关系;
2、重写需要子类和父类中的两个函数的函数原型完全相同;重载要求两个函数参数列表不同;
3、在重写关系中,调用具体调用哪一个函数是根据(对象对应存储空间的实际类型)为准的,这涉及到动态绑定和静态绑定的问题,也就是虚函数的调用机制,而函数重载主要是靠形参列表的不同来区分具体调用哪个函数的。