重载与覆盖
- 重载:Overload
- 覆盖:Override
- 二者本身没有任何关系,只是英文单词长得像而已。
重载(Overload)
- 重载指的是同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数。
- 重载不关心函数返回类型。
- 作用是解决了解决了同一个类中,相同的功能方法名不同的问题。
实例:
class A{
public:
void test(int i);
void test(double i);
void test(int i, double j);
void test(double i, int j);
int test(int i); //错误,非重载
};
在上面的例子中,前四个函数互为重载函数,最后一个和其他的并不是重载关系。
覆盖(Override)
- 覆盖也称为重写,指的是派生类中存在重新定义的函数。其函数名、参数列表、返回值类型,所有都必须和基类中被覆盖的函数一致,只有函数体不同。
- 派生类在调用时,会调用派生类的这个覆盖函数,而不会调用被覆盖函数,
- 覆盖的基类中被覆盖的函数必须有virtual标识。即:
- 在子类中重写了父类的虚函数,那么子类对象调用该重写函数,调用的是子类内部重写的虚函数,而不是父类继承下的虚函数(这就是多态的动态实现)。
- 在子类中重写父类的虚函数,如果用一个父类的指针指向子类对象,那么这个父类的指针所调用的就是该重写的虚函数;相反,如果用一个父类的指针指向父类的对象,调用的就是父类的虚函数。
- 覆盖方法必须和父类中被覆盖的方法具有相同的方法名称、输入参数和返回值类型。
- 覆盖方法不能使用比父类中被覆盖方法更严格的访问权限。
- 覆盖方法不能比父类中被覆盖方法抛出更多的异常。
- 实例:
class A {
public:
virtual void fun() {
cout<<"A::fun"<<endl;
}
};
class B : public A {
void fun() {
cout<<"B::fun"<<endl;
}
};
int main() {
A a;
B b;
A *pa = &a;
pa->fun();
pa = &b;
pa->fun();
return 0;
}
输出结果:
A::fun()
B::fun()
小结
重载和覆盖的区别
- 范围区别:
重载和被重载的函数在同一个类中,而覆盖和被覆盖的函数在不同的类中。 - 参数区别:
重载和被重载的函数参数列表一定相同,而覆盖和被覆盖的函数参数列表一定相同。 - virtual的区别:
重载函数和被重载函数可以用virtual修饰,也可以不用,而覆盖的积累必须要有virtual修饰。