重载,名字修饰,重写
重载(overload)定义
允许存在多个同名函数,而这些函数的参数不同。
重载规则
- 被重载的方法 必须改变参数列表;
- 被重载的方法可以改变返回值类型,但是不能通过返回值类型来区分重载的不同函数。
原因:
(1)int func(int x,int y);
(2)float func(int x,int y);
调用:(3)func(2,3);
调用语句中根本没包含返回值,就会产生二义性(调1还是调2?) 所以,就无法区分不同的重载函数了。
名字修饰(name mangling)
在c++中,重载是通过对函数进行“重整(name mangling)”实现的。
实现方法为:编译器根据函数的不同参数表,对同名函数的名称进行修饰,这时,对于编译器而言,这些同名函数就成了不同的函数,他们的编译地址在编译期就绑定了。每个重载的方法(或者构造函数)都必须有独一无二的参数类型列表。
“类似改名”:
一个实例
代码
#include <iostream>
using namespace std;
class A {
public:
int add(int x, int y) {
return x + y;
}
int add(int x, int y, int z) {
return x + y + z;
}
float add(float x, float y) {
return x + y;
}
};
int main() {
A a;
cout << a.add(1,2)<<endl;
cout << a.add(1, 2, 3) << endl;
cout << a.add(1.123f, 2.123f) << endl;
}
结果
仅仅返回值不同,不能区别重载的不同函数。
c++中若要引用c语言代码,必须加上extern "c"说明。
原因:
c语言中没有重载机制,所以c编译器并不会对函数进行重整,即不加相应的修饰符。
如果不加 extern “c”,那么c++就会对其中的函数进行重整,从而找不到相关的正确的函数体。
只有加了之后,c++才不会对其进行重整,因此按照c的格式调用,使用相应的c代码。
struct 和class的区别
- struct 默认public。若在struct内部,忘记在其中成员函数前加public,则在main函数值仍然可以调用这些函数,默认公有。
- class 默认private,若在class内部,忘记在其中成员函数前加public,则在main函数值无法调用这些函数,默认私有。
重写(override)
在继承关系中,如果派生类重新定义一个方法,如果其名称,返回类型及参数签名与基类中的某个方法的名称,返回类型及参数名称相匹配,那么派生类的方法覆盖了基类的方法,叫方法覆盖/方法重写。(继承中的改写)。
特点
- 派生类的方法名称,返回值类型,参数签名必须与基类的方法名称,返回值类型,参数签名相同。
- 派生类的方法不能缩小基类方法的访问权限,只能扩大不能缩小。(在基类中为protected,则再派生类中只能说protected/public,不能是private)。
重载(overload)和重写(override)区别
相同点
函数名相同。
不同点
- 方法重载发生在同一个类的内部方法中,而方法重写发生在继承关系中,派生类重写基类中的方法。
- 方法重载不要求返回类型是否一致,而方法重写要求返回类型必须一致。
- 方法重载要求方法的参数签名必须不一致,而方法重写要求方法的参数签名必须一致。
- 重写需要虚函数(virtual)支持。重载需要名字修饰(name mangling)来支持。