P2-c++函数详解-02函数重载详细介绍

1.函数重载的概念

在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数!

函数重载的关键是函数的参数列表——也称为函数特征标。如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则它们的特征标相同,而变量名是无关紧要的。c++允许定义名称相同的函数,条件是它们的特征标不同。如果参数数目或参数类型不同,则特征标也不同。

2.一个简单的演示例子

在这里插入图片描述

1. 演示的源码

#include <iostream>
using namespace std;

void print(const char *str, int width);		//#1
void print(double d, int width);			//#2
void print(long l, int width);				//#3
void print(int i, int width);				//#4
void print(const char *str);				//#5

int main()
{
	//梦悦foundation
	unsigned int year = 2021;
	print("meng-yue-foundation", 15);
	print("meng-yue-foundation");
	print(1999.0, 10);
	print(29, 12);
	print(19L, 15);

	//print(year, 6);
    return 0;
}

void print(const char *str, int width)
{
	cout << "#1 print(const char *str, int width)" << endl;
}
void print(double d, int width)			
{
	cout << "#2 print(double d, int width)" << endl;
}
void print(long l, int width)			
{
	cout << "#3 print(long l, int width)" << endl;
}
void print(int i, int width)
{
	cout << "#4 print(const char *str, int width)" << endl;
}
void print(const char *str)			
{
	cout << "#5 print(const char *str)" << endl;
}


运行结果如下

book@book-desktop:~/meng-yue/c++/function/02$ ./FunctionOverload
#1 print(const char *str, int width)
#5 print(int , int width)
#2 print(double d, int width)
#4 print(const char *str, int width)
#3 print(long l, int width)
book@book-desktop:~/meng-yue/c++/function/02$

2. unsigned int year = 6, print(year, 6);与谁匹配?

#include <iostream>
using namespace std;

void print(const char *str, int width);		//#1
void print(double d, int width);			//#2
void print(long l, int width);				//#3
void print(int i, int width);				//#4
void print(const char *str);				//#5

int main()
{
	//梦悦foundation
	unsigned int year = 2021;
	print("meng-yue-foundation", 15);
	print("meng-yue-foundation");
	print(1999.0, 10);
	print(29, 12);
	print(19L, 15);

	print(year, 6);
    return 0;
}

void print(const char *str, int width)
{
	cout << "#1 print(const char *str, int width)" << endl;
}
void print(double d, int width)			
{
	cout << "#2 print(double d, int width)" << endl;
}
void print(long l, int width)			
{
	cout << "#3 print(long l, int width)" << endl;
}
void print(int i, int width)
{
	cout << "#4 print(const char *str, int width)" << endl;
}
void print(const char *str)			
{
	cout << "#5 print(int , int width)" << endl;
}

编译报错了,匹配的函数太多了,有歧义!

book@book-desktop:~/meng-yue/c++/function/02$ g++ -o FunctionOverload FunctionOverload.cpp
FunctionOverload.cpp: In function ‘int main():
FunctionOverload.cpp:20: error: call of overloaded ‘print(unsigned int&, int)’ is ambiguous
FunctionOverload.cpp:4: note: candidates are: void print(const char*, int) <near match>
FunctionOverload.cpp:5: note:                 void print(double, int)
FunctionOverload.cpp:6: note:                 void print(long int, int)
FunctionOverload.cpp:7: note:                 void print(int, int)
book@book-desktop:~/meng-yue/c++/function/02$

首先它是unsigned int类型,他不与任何原型匹配。没有匹配的原型并不会自动停止使用其中的某个函数。因为c++将尝试使用标准类型转换强制进行匹配。如果#2原型是print()唯一的原型。则函数调用print(year,6)将把year转换为double类型。但在上面的代码中,有4个将数字作为第一个参数的原型。因此有4种转换year的方式。在这种情况下,c++将拒绝这种函数调用,并将其视为错误!

3. 一些看起来彼此不同的特征标是不能共存的

例如,请看下面的两个原型。

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

从形式上来看,好像是符合函数重载的,因为他们的特征标看起来不同,但是编译器看到下面的代码不知道使用哪个原型

cout << cube(x);

为了避免这种混乱,编译器在检查特征标的时候,将把类型引用和类型本身视为同一个特征标。

3. const和非const在函数函数重载当中的注意事项

void function(char *bits);
void function(const char *cbits);

void demo(char *bits);
void demo_const_char(const char *bits);

下面列出了各种函数调用对应的原型

const char p1[20] = "梦悦foundation";
char p2[30] = "梦悦foundation";
function(p1);//------>匹配void function(const char *cbits);
function(p2);//------》匹配void function(char *bits);

demo(p1);//------》什么都不匹配,还会报错
demo(p2);//-------》匹配void demo(char *bits);

demo_const_char(p1);
demo_const_char(p2);//两个都匹配到 void demo_const_char(const char *bits);

function()函数有两个原型,一个用于const 指针,一个用于常规指针,编译器将根据实参是否为const来决定使用哪个原型。

demo()函数只会匹配非const 参数, 而demo_const_char()函数可以与带const 或者不带 const参数 匹配,之所以出现这种差别,主要是由于允许将 非 const值赋给 const 形参是合法的,但是 将const 值赋值给 非const 是不合法的,因为合法的话,不就相当于可以更改const的值了吗?

1. demo_const.cpp 用来演示const与非const在函数重载当中的注意事项

demo_const.cpp 的源码


#include <iostream>
using namespace std;
void function(char *bits);
void function(const char *cbits);

void demo(char *bits);
void demo_const_char(const char *bits);

int main(int argc, char *argv[])
{
	const char p1[20] = "梦悦foundation";
	char p2[30] = "梦悦foundation";
	function(p1);//------>匹配void function(const char *cbits);
	function(p2);//------》匹配void function(char *bits);
	
	//demo(p1);//------》什么都不匹配,还会报错
	demo(p2);//-------》匹配void demo(char *bits);
	
	demo_const_char(p1);
	demo_const_char(p2);//两个都匹配到 void demo_const_char(const char *bits);
	return 0;
}


void function(char *bits)
{
	cout << " function(char *bits) " << endl;
}
void function(const char *cbits)
{
	cout << " function(const char *cbits) " << endl;
}

void demo(char *bits)
{
	cout << " demo(char *bits) " << endl;
}

void demo_const_char(const char *bits)
{
	cout << " demo_const_char(const char *bits) " << endl;
}


这一行如果不注释掉还会报错//demo(p1);

book@book-desktop:~/meng-yue/c++/function/02$ g++  -o demo_const demo_const.cpp
demo_const.cpp: In function ‘int main(int, char**):
demo_const.cpp:17: error: invalid conversion from ‘const char*’ to ‘char*’
demo_const.cpp:17: error:   initializing argument 1 of ‘void demo(char*)’
book@book-desktop:~/meng-yue/c++/function/02$

说明了 const char * 确实不能转化成 char *

把报错那一行注释掉,看一下运行结果

book@book-desktop:~/meng-yue/c++/function/02$ ./demo_const
 function(const char *cbits)
 function(char *bits)
 demo(char *bits)
 demo_const_char(const char *bits)
 demo_const_char(const char *bits)
book@book-desktop:~/meng-yue/c++/function/02$

4. 去哪获取笔记和详细的资料

代码资料的路径
在这里插入图片描述

1 微信公众号,梦悦foundation

在这里插入图片描述

2 公众号里点击IT资源,有链接

3 后台回复 c++资料

4 加up主微信,进学习交流群,大家一起带你飞!

在这里插入图片描述

5. 获取到的笔记怎么使用

1 pdf文件

2 html格式文件

3 蚂蚁笔记

4 印象笔记

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值