前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++:01---函数重载、缺省参数

C++:01---函数重载、缺省参数

作者头像
用户3479834
发布于 2021-02-03 07:25:34
发布于 2021-02-03 07:25:34
94600
代码可运行
举报
文章被收录于专栏:游戏开发司机游戏开发司机
运行总次数:0
代码可运行

一、函数重载

  • 概念:在同一作用域内,声明几个功能相同(或类似)的同名函数,实现功能类似但所处理数据类型不同的函数
  • 函数重载的条件
    • 函数名必须相同
    • 函数的参数不同(参数个数不同或参数对应位置的数据类型不同)
    • 作用域必须相同
    • 函数重载与函数的返回值无关

哪些情况不构成重载、构成重载

  • ①顶层const不构成重载,所以下面的两个函数不构成重载
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int add(int a,int b);

int add(const int a,const int b);
 
  • ② 普通引用不构成重载,所以下面的两个函数不构成重载
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int add(int a,int b);
 
int add(int& a,int& b);
 
  • ③常量引用或者常用指针构成重载,所以下面两组函数都构成重载(因为const对象不能转换为其它类型,所以只能将const对象传递给const形参。相反,非常量对象可以传递给任何类型,所以非const对象都可以传递给下面4个函数)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int add(int* a,int* b);
 
int add(const int* a,const int* b);
 

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int add(int& a,int& b);
 
int add(const int& a,const int& b);
 
  • ④ const函数与非const函数构成重载
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int add(int a,int b);
 
int add(int a,int b)const;
 

函数重载与数据类型之间的关系

  • 在书写函数时,我们要确定自己的需求。如果形参的数据类型没有设置好,编译器会报错

案例一:

  • 下面的add(3.1,4.25)函数参数为double类型,调用此函数时,编译器没有找到有double类型的函数,于是就去类型转换寻找适合的函数,发送double可以转换为int,也可以转换为float。于是产生二义性,程序报错
  • 但是可以通过在数字后面给出F或者强制类型转换来告诉编译器具体调用哪一个函数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int add(int a,int b);
 
float add(float a,float b);
 
int main()
 
{
 
add(1,2);
 
add(3.1,4.25);//报错
 
add(3.1F, 4.25F);//正确
 
add((float)3.1,(float)4.25);//正确
 
}
 
  • 例如:下面的3.14会转换为float也会转换为long,因此也报错
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int func(long a);
 
int func(float a);
 
int main()
 
{
 
func(3.14);//报错
 


 
}

案例二:

  • 下面的func函数调用也会产生二义性
    • 第一步:调用func时,参数1为int,此时func去匹配两个重载函数,发现int func(int a,int b);比较合适,于是就调用此函数
    • 第二步:匹配到参数2时,3.14为double类型,编译器发现int func(double a,double b);比较合适,于是就调用此函数
    • 最后,编译器产生二义性报错
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int func(int a,int b);  
int func(double a,double b);  
int main()  
{  
func(1, 3.14); //报错  
}
 

案例三:

  • 常量形参与非常量形参的调用(上面,介绍过常量形参与非常量形参形成重载)
    • 执行func(a);时,因为a为非常量,因此两个函数都可以调用。但是因为把非常量赋值给常量需要强制类型转换,因此就调用int func(int &s);
    • 执行func(b);时,传入的b是const类型,因此不能把普通引用绑定到const对象上,所以只调用int func(const int &s);
  • 常量指针的原理也是如此(详情见const讲解文章)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int func(int &s);
 
int func(const int &s);
 
int main()
 
{
 
int a = 10;
 
const int b = 20;
 
func(a); //调用int func(int &s);
 
func(b); //调用int func(const int &s);
 
}
 

函数重载示例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct myPoint 
 
{
 
 int row, col;
 
};
 
myPoint add(myPoint a, myPoint b)
 
{
 
	myPoint tempPoint;
 
	tempPoint.col = a.col + b.col;
 
	tempPoint.row = a.row + b.row;
 
 return tempPoint;
 
}
 
int add(int a, int b)
 
{
 
 return a + b;
 
}
 
double add(double a, double b)
 
{
 
 return a + b;
 
}
 
int main()
 
{
 
 cout << add(1, 2) << endl;  //3
 
 cout << add(2.5,3.1) << endl; //5.6
 
 return 0;
 
}
 

函数重载与作用域的关系

  • 下面的代码不规范(不应该在一个函数中声明一个函数)。但是只是为了函数重载与作用域的关系
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
string read();
 
void print(const string&);
 
void print(double);
 
int main()
 
{
 
bool read = false;
 
int val = 1;
 
string s = read(); //错误,read函数与局部变量read冲突
 


 
void print(int);  //定义一个参数为int的print函数
 
print("Value");  //错误,print(const string&);被隐藏
 
print(val);    //正确,调用print(int)
 
print(3.14);   //正确,调用print(int)
 
}
 

const_cast与重载

const_cast介绍

功能:用来将对象的常量性移除

注意事项:

  • 只能改变运算对象的底层const

const_cast常用于有函数重载的上下文

演示案例

代码语言:javascript
代码运行次数:0
运行
复制
  • 当我们去掉某个对象的const性质之后,编译器就不再阻止我们对该对象进行写操作了,因此写操作会产生未定义的后果
  • const char *pc;
  • //正确,但是通过p写值是未定义的行为
  • 将底层const对象转换为非const对象

演示案例

代码语言:javascript
代码运行次数:0
运行
复制
  • const char* cp;
  • //错误,static_cast不能去除const性质
  • static_cast<string>(cp);
  • //错误,const只能去除const性质,但是不能进行数据类型的转换
  • const_cast只能改变表达式的常量属性,而不能改变表达式的数据类型

现在我们有下面一个这样的函数,其中参数与返回值都是const类型的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//比较两个string对象的长度,返回较短的那个引用

const string &shortString(const string &s1, const string &s2)

{

return s1.size() <= s2.size() ? s1 : s2;

}
 
  • 如果我们将两个非const string对象传递给这个函数,那么返回的仍然是const string的引用
  • 因此,我们希望有一种新的函数,当传入给它的实参不是const时,也得到一个非const对象的引用,那么使用const_cast可以做到这一点:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//比较两个string对象的长度,返回较短的那个引用
 
const string &shortString(const string &s1, const string &s2)
 
{
 
return s1.size() <= s2.size() ? s1 : s2;
 
}
 
string &shortString(string &s1, string &s2)
 
{
 
//调用const string&类型的shortString
 
auto &r = shortString(const_cast<const string&>(s1),
 
·const_cast<const string&>(s2));
 
//然后将返回的结果去掉const性质
 
return const_cast<string&>(r);
 
}
 

二、缺省参数(默认实参)

  • 概念:人为的为函数定义一个或多个默认参数,在调用函数时,它们被赋予一个相同的值
  • 注意事项:
    • 如果函数没有声明,则默认形参直接写在函数定义时
    • 如果函数有声明和定义,则默认形参只可写在函数声明中,函数定义时不可以写
    • 默认形参只能写在最后,或其及其后面都是默认形参
    • 缺省参数是在编译阶段决定的,所以只能用常量或者全局变量作为缺省参数
    • 函数调用时给出实参,会覆盖掉默认参数

缺省参数示例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int add(int a, int b,int c=10)
 
{
 
 return a + b+c;
 
}
 
int main()
 
{
 
 cout << add(1, 2) << endl;  //13
 
 cout << add(1,2,50) << endl; //53
 
 return 0;
 
}
 

使用全局变量初始化缺省参数

  • 缺省参数可以使用一个函数外的变量/常量初始化。但是不能用函数内的局部变量初始化
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int a=10;
 
int b=20;
 
char c='a';
 
void func(int num1=a,int num2=b,char s=c);
 
  • 注意事项:虽然可以用全局变量初始化缺省参数,但是如果全局变量被改变了,再次调用这个函数缺省参数的值也会改变
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int a=10;
 
int b=20;
 
char c='a';
 
void func2()
 
{
 
a=66; //改变全局变量
 
int b=30; //局部变量,但是不影响全局变量
 
func(); //调用func(66,20,'a');
 
}
 

函数的调用

  • 原理:使用的函数逐个入栈,main函数中调用到某函数时,跳到栈对应的函数位置,并返回结果
  • 普通函数的调用与内联函数的内存模型

三、函数重载冲突

  • 函数重载与缺省参数冲突的特殊情况
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int add(int a, int b,int c=10)
{
	return a + b+c;
}
int add(int a, int b)
{
	return a + b;
}
int main()
{
	cout << add(1, 2) << endl;//报错,对函数的调用不明确
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 游戏开发司机 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、函数重载
    • 哪些情况不构成重载、构成重载
    • 函数重载与数据类型之间的关系
    • 案例一:
    • 案例二:
    • 案例三:
    • 函数重载示例代码
    • 函数重载与作用域的关系
    • const_cast与重载
    • 演示案例
    • 演示案例
  • 二、缺省参数(默认实参)
    • 缺省参数示例代码
    • 使用全局变量初始化缺省参数
  • 三、函数重载冲突
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档