重载重写与覆盖
覆盖与重写、重载区别是什么?effective cpp 条款33
太长不看
Overload(重载):重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型(参数列表不同)。调用的时候根据函数的参数来区别不同的函数。有以下特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual关键字可有可无;
Override(重写):覆盖是指派生类重新实现(或者改写)了基类的成员函数,有以下特征:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual关键字
覆盖/隐藏:
函数隐藏指不同作用域中定义的同名函数构成函数隐藏(不要求函数返回值和函数参数类型相同)。比如派生类成员函数屏蔽与其同名的基类成员函数、类成员函数屏蔽全局外部函数。
Overload重载
重载从overload翻译过来,是指同一可访问区内被声明的 几个具有不同参数列表(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。
- 相同的范围(在同一个作用域中)
- 函数名字相同
- 参数不同列表
virtual关键字可有可无- 返回类型可以不同
1 | int test(); |
Override重写
重写翻译自override,是指派生类中存在重新定义的函数。其 函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。
- 不在同一个作用域(分别位于派生类与基类)
- 函数名字相同
- 参数相同列表(参数个数,两个参数列表对应的类型)
- 基类函数必须有
virtual关键字,不能有static,大概是多态的原因吧… - 返回值类型相同(或者协变),否则报错
- 重写函数的访问修饰符可以不同。尽管
virtual是private的,派生类中重写改写为public,protected也是可以的
1 | class Base{ |
协变 covariant
在C++中,协变(covariant)或者 返回类型协变(return type covariance,体现在:派生类中的返回类型可以是基类(父类)中返回类型的子类型。
换句话说,如果一个虚函数在基类中返回的是基类类型的指针或引用,那么派生类可以重写该虚函数并返回基类类型的子类类型的指针或引用。
派生类中重写的虚函数可以具有比基类更具体的返回类型。
这种协变的能力使得在使用多态时更加灵活,可以根据具体的派生类返回不同的子类型,而不需要进行显式的类型转换。
Hide覆盖(隐藏)
隐藏是指 派生类的函数屏蔽了与其同名的基类函数。注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏。
- 不在同一个作用域(分别位于派生类与基类)
- 函数名字相同
- 返回类型可以不同
- 参数不同,此时,不论有无
virtual关键字,基类的函数将被隐藏(注意别与重载混淆)而不是被重写 - 参数相同,但是基类函数有无
virtual关键字都会被隐藏。此时,基类的函数被隐藏(注意别与覆盖混淆)
1 |
|
总结
重载代表了静态多态,在同一作用域下,同名函数可以表现出不同的行为;
重写则是动态多态,不同作用域(基类和派生类)下,通过对象指针或引用,使得同名同参函数展现出不同行为;
覆盖则是不同作用域下的名称掩盖(隐藏),要求使用派生对象调用函数。