C++中函数重载

序言

函数重载是C++在C语言基础上新增的特性,函数重载指的是可以有多个同名的函数,这就像你可以在学校以一个学生的身份读书,也可以在家以一个子女的身份帮爸妈干活。函数重载有着十分重要的意义,下面是其中几点:

  • 试想如果没有函数重载机制,如在C中,你必须要这样去做:为这个print函数取不同的名字,如print_int、print_string。这里还只是两个的情况,如果是很多个的话,就需要为实现同一个功能的函数取很多个名字,如加入打印long型、char*、各种类型的数组等等。这样做很不友好!
  • 类的构造函数跟类名相同,也就是说:构造函数都同名。如果没有函数重载机制,要想实例化不同的对象,那是相当的麻烦!
  • 操作符重载,本质上就是函数重载,它大大丰富了已有操作符的含义,方便使用,如+可用于连接字符串等!

下面我们介绍一些关于重载的基础知识。

基本认识

函数重载的关键是函数的参数列表,也叫做函数特征标,如果两个函数的参数数目和类型都相同,同时参数的排列顺序也相同,变量名是无关紧要的,C++允许定义名称相同的函数,前提是它们特征标不同,例如,可以定义以下一系列函数:

void print(const char *str, int width);
void print(double d, int width);
void print(long l, int width);
void print(int i, int width);
void print(const char *str);

使用print函数的时候,编译器将根据所采取的用法使用有相应特征标的原型,如下所示:

print("apple", 5);
print("apple");
print(1999.0, 10);
print(1999, 12);
print(1999L, 15);

在使用被重载的函数时,要确保参数类型是正确的,例如下面的语句:

unsigned int year = 2001;
print(year, 6);

这里的调用方式并不会有函数与它匹配,但C++也不会直接报错,他会首先将所给数据进行强制类型转换变成可以传送的数据,但是我们发现,这里有三个函数可以接收这种转换,所以就产生了冲突,这里C++才会报错。

一些特征标不同的函数,但在实际使用过程中存在歧义,所以C++也是不允许的,如下所示:

double cube(double x);
double cube(double &x);

在如下的调用过程中,C++并不能区分它们

m = cuble(x);

是特征标,而不是函数类型使得可以对函数进行重载,例如下面的两个声明是互斥的

long gronk(int n, float n);
double gronk(int n, float n);

C++不允许这样的重载方式,返回值类型可以不同,但是特征标也必须不同。

long gronk(int n, float n);
double gronk(float n, float n);

重载引用参数

类设计和STL经常使用引用参数,因此知道不同引用类型的重载很有用。请看下面三个原型:

void sink{double & r1};
void sank{const double & r2};
void sunk{double && r3};

左值引用参数r1与可修改的左值参数(如double变量)匹配;const左值引用参数r2与可修改的左值参数、const左值参数和右值参数(如两个double值的和)匹配;最后,左值引用参数r3与左值匹配。注意到与r1或r3匹配的参数都与r2匹配。这就带来了一个问题:如果重载使用这三种参数的函数,结果将如何?答案是将调用最匹配的版本

void staff(double & rs);//匹配可修改的左值
void staff(const double &rcs);//匹配右值和常量左值
void stove(double & r1);//匹配可修改的左值
void stove(const double & r2);//匹配常量左值
void stove(double && r3);//匹配右值

下面是一些使用示例:

double x = 55.5;
const double y = 32.0;
stove(x);//调用 stove(double &)
stove(y);//调用 stove(const double &)
stove(x + y);//调用 stove(double &&)

我们可以看到,上面示例的调用方式完全复合调用最匹配的版本这个原则。

如何使用函数重载

重载虽好,可不要乱用哦!!仅当函数基本上执行相同的任务,但使用不同形式的数据时,才使用函数重载。

名称修饰

C++如何跟踪每一个重载函数呢?在编译阶段,C++编译器会执行一种叫做名称修饰的操作,它根据函数中指定的形参类型对每个函数名进行加密。至于怎么加密,不同的编译器会有不同的机制。
这个就有点像python中的变量私有化技术:name mangling,在我的这篇文章的末尾关于python中局部变量的实现中有简要介绍。


结论:函数重载具有十分重要的意义,它极大地丰富了编程语言的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值