C++ 函数 函数的重载 有默认参数的函数
函数的重载
C++允许用同一函数名定义多个函数,这些函数的参数个数和参数类型不同。这就是函数的重载(function overloading)。
int max1(int a,int b, int c);
double max2(double a,double b,double c);
long max3(long a,long b,long c);
#include <iostream>
using namespace std;
int main( )
{
int max(int a,int b,int c); //函数声明
int max(int a,int b); //函数声明
int a=,b=-,c=;
cout<<″max(a,b,c)=″<<max(a,b,c)<<endl;
cout<<″max(a,b)=″<<max(a,b)<<endl; }
int max(int a,int b,int c) //求3个整数中的最大者
{
if(b>a) a=b;
if(c>a) a=c;
return a;
}
int max(int a,int b) //求两个整数中的最大者
{
if(a>b) return a;
else return b;
}
参数的个数和类型可以都不同。但不能只有函数的类型不同而参数的个数和类型相同。
也就是说重载与否是由参数决定的,而不是返回值决定!!!
这里引入一个概念:
函数签名:函数的名称及其参数类型组合在一起,就定义了一个唯一的特性,称为函数签名。(不包括返回类型)
c++要求重载函数具有不同的签名。返回类型不是函数签名的一部分。
C++ requires that overloaded functions have distinct signature.The return type is not part of a function’s signature.
例如:
int main()
{
int f(int);
long f(int); // error C2556: “long f(int)”: 重载函数与“int f(int)”只是在返回类型上不同
void f(int); // error C2556: “void f(int)”: 重载函数与“int f(int)”只是在返回类型上不同
return ;
}
下面介绍重载中的二义性问题:
如果两个不同宽度的数据类型进行运算时,编译器会尽可能地在不丢失数据的情况下将它们类型统一。若float和double运算时,如果不显式地指定为float型,会自动转换成double型进行计算。一个整数类型int和一个浮点类型float运算时,如果不显式地指定为int型,C++会先将整数转换成浮点数。
int main()
{
float x = 2.1f;
float y = 2.1; //warning C4305: “初始化”: 从“double”到“float”截断
return ;
}
上述 语句中float y=2.1 我们以为它是一个float类型,但编译器却把它认为是double(因为小数默认是double型),所以给出了警示信息,一般要定义float类型,则应该改成2.1f。
通常编译器会按照返回类型、参数类型、参数数量区 区别调用哪个重载函数,但有时候,数据类型自动转换机制会使编译器进入死胡同。
float fun(float a);
double fun(double a);
int main()
{
float x;
x = fun(5.1);
x = fun(); // error C2668: “fun”: 对重载函数的调用不明确
return ;
}
在这里编译器不知道应该讲x=fun(5)转换成float还是double。
有默认参数的函数
一般情况下,在函数调用时形参从实参那里取得值,因此实参的个数应与形参相同。C++允许在定义函数时给其中的某个或某些形式参数指定默认值,这样,当发生函数调用时,如果省略了对应位置上的实参的值时,则在执行被调函数时,以该形参的默认值进行运算。有时多次调用同一函数时用同样的实参,给形参一个默认值,这样形参就不必一定要从实参取值了。如有一函数声明
float area(float r=6.5);
area( ); //相当于area(6.5);
如果不想使形参取此默认值,则通过实参另行给出
area(7.5); //形参得到的值为7.5,而不是6.5
实参与形参的结合是从左至右顺序进行的。因此指定默认值的参数必须放在形参表列中的最右端,否则出错。例如:
void fun1(float a,int b=,int c,char d=’a’); //不正确
void fun2(float a,int c,int b=, char d=’a’); //正确
在使用带有默认参数的函数时有两点要注意:
(1)如果函数的定义在函数调用之前,则应在函数定义中给出默认值。如果函数的定义在函数调用之后,则在函数调用之前需要有函数声明,此时必须在函数声明中给出默认值,在函数定义时可以不给出默认值。
(2)一个函数不能既作为重载函数,又作为有默认参数的函数。因为当调用函数时如果少写一个参数,系统无法判定是利用重载函数还是利用默认参数的函数,出现二义性,系统无法执行。
void fun(int); //重载函数之一
void fun(int,int = ); //重载函数之二,带有默认参数
void fun(int = ,int = ); //重载函数之三,带有默认参数
fun(); //error: 到底调用3个重载函数中的哪个?
fun(,) //error:到底调用后面2个重载函数的哪个?
默认参数一般在函数声明中提供。如果程序中既有函数的声明又有函数的定义时,则定义函数时不允许再定义参数的默认值。
void fun(int x = ,int y = );
void main() {}
void fun(int x = , int y = ) { }
// error C2572: “fun”: 重定义默认参数 : 参数 2
// error C2572: “fun”: 重定义默认参数 : 参数 1
默认值可以是全局变量、全局常量,甚至是一个函数。例如:
int a=;
int fun(int);
int g(int x;fun(a)); //OK,允许默认值为函数
默认值不可以是局部变量,因为默认参数的函数调用是在编译时确定的,而局部变量的位置与值在编译时均无法确定。
例如:
int main()
{
int i;
void g(int x=i); // error C2587: “i”: 非法将局部变量作为默认参数
return ;
}
C++ 函数 函数的重载 有默认参数的函数的更多相关文章
- c++-内联函数和函数重载和默认参数和函数指针
内联函数 C++ 内联函数是通常与类一起使用.如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方. 对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编 ...
- c++有默认参数的函数---4
原创博客:转载请标明出处:http://www.cnblogs.com/zxouxuewei/ 1.默认参数的目的 C++可以给函数定义默认参数值.通常,调用函数时,要为函数的每个参数给定对应的实参. ...
- [C++程序设计]有默认参数的函数
实参与形参的结合是从左至右顺序进行的.因此指定默认值的参数必须放在形参表列中的最右端,否 则出错.例如: void f1(float a,int b=0,int c,char d=′a′); //不正 ...
- PHP_零基础学php_3PHP函数、传参函数、默认参数、函数返回值
<?php function say_hello() //无参数 { $name="tang"; echo "hello,".$name; echo &q ...
- 【c++】类中带默认参数的函数
反思两个问题 1. 带默认参数的函数,为何声明.定义不能同时有参数? 2. 带默认参数的函数, 为何带默认参数的参数靠后站? 上程序 #include <iostream> #includ ...
- php课程 3-12 带默认参数的函数怎么写
php课程 3-12 带默认参数的函数怎么写 一.总结 一句话总结:多看学习视频啊 1.带默认参数的函数怎么写? 直接等于号接默认参数,和js里面一模一样 2.带默认参数的函数的注意事项是什么? 默认 ...
- js课程 2-7 带默认参数的函数怎么写
js课程 2-7 带默认参数的函数怎么写(注意参数顺序) 一.总结 一句话总结:默认参数一定要放在最后面,而且还有注意你调用参数的时候给参数的顺序习惯.直接加个等于号就可以是默认参数.function ...
- js中ajax连接服务器open函数的另外两个默认参数get请求和默认异步(open的post方式send函数带参数)(post请求和get请求区别:get:快、简单 post:安全,量大,不缓存)(服务器同步和异步区别:同步:等待服务器响应当中浏览器不能做别的事情)(ajax和jquery一起用的)
js中ajax连接服务器open函数的另外两个默认参数get请求和默认异步(open的post方式send函数带参数)(post请求和get请求区别:get:快.简单 post:安全,量大,不缓存)( ...
- Python基础之定义有默认参数的函数
1. 构建有默认参数的函数 当我们在构建一个函数或者方法时,如果想使函数中的一个或者多个参数使可选的,并且有一个默认值,那么可以在函数定义中给参数指定一个默认值,并且放到参数列表的最后就行了.比如: ...
随机推荐
- HDU 1114(没有变形的完全背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114 Piggy-Bank Time Limit: 2000/1000 MS (Java/Others ...
- elasticserach 索引删除 源码分析
索引的构成 在看IndicesService服务中移除索引的前提,先了解一个Index类的构成,也就是索引的一些基本信息,代码贴图如下: 主要的信息就两个:一个是name,表示索引名称,一个是uu ...
- STM32的AFIO时钟什么时候需要开启
相比于普通单片机,STM32 拥有复杂的时钟系统,相应的控制器称为 RCC(Reset Clock Controller,复位与时钟控制器).每个外设都配备了外设时钟的开关,当我们不使用某个外设时,可 ...
- Go语言中的常量
1 概述 常量,一经定义不可更改的量.功能角度看,当出现不需要被更改的数据时,应该使用常量进行存储,例如圆周率.从语法的角度看,使用常量可以保证数据,在整个运行期间内,不会被更改.例如当前处理器的架构 ...
- Nginx-------Nginx的安装和多域名配置
Nginx安装 centos6.x yum默认没有nginx的软件包 安装方式: 到nginx下载页面http://nginx.org/en/linux_packages.html#stable,复制 ...
- swt TableViewer
http://blog.163.com/bluefield_wild/blog/static/8182709520085612235336/ package list; import java.uti ...
- 【Vijos】lxhgww的奇思妙想
题面 题解 求$k$级祖先孙子 为什么要用长链剖分啊??? 倍增并没有慢多少... 其实是我不会 长链剖分做这道题还是看这位巨佬的吧. 代码 #include<bits/stdc++.h> ...
- CentOS7 msmtp+mutt发送邮件
一.安装软件 # msmtp软件各版本下载地址:https://marlam.de/msmtp/download/ [root@--- ~]# wget https://marlam.de/msmtp ...
- idea maven项目要想正常编译成war包,需要做的处理
以及右键项目 - Build(第一次打包成war) (第一次Build) - ReBuild(非第一次打包成war)(非第一次Build) 按照顺序做一到几次,就可以成功编译成war包了(如果rebu ...
- 亿级PV请求的三种负载均衡技术
在互联网+不断渗透到生活中的今天,各种各样的网络服务存在在我们身边,他们的访问流量也是大得惊人.一个大型网站(百万PV以上)想要正常访问,单单靠一台服务器是不可能提供稳定服务的.这时候就需要用负载均衡 ...