一、函数重载

普通函数重载的关键是参数列表---也称函数特征标。函数参数中有以下情况可以出现重载:

1、  形参个数不同

2、  形参的类型不同

3、  形参的类型和个数都不同

const形参和函数重载

重载无法区分const和非const

首先分清楚什么是顶层const,什么是底层const

前提是有一个指针或是引用,指向一个数据,顶层const表示该指针不能改变(不能重新指向另一个数据),底层const表示该指针指向的数据不能被改变。(顶层const可以理解成不同的类型)

底层const写法:

Int num = 1;

const int * p = #      //等价于int const * p = &num

顶层const写法:

Int num = 1;

int * const p = #

当指针作为函数参数时,顶层const可以区分,而底层const不可区分

下面的写法出现重复定义:

double cube(double x)

double cube(const double x)

下面的底层const可以区分

void dribble(char* bits);

void dribble(const char * bits);

下面的顶层const不可区分:

void dribble(char* bits);

void dribble(char * const bits);

同理,引用的情况是可以区分的

double cube(double& x)

double cube(const double & x)

const修饰函数

如果const是在函数结尾,表示整个函数体内代码不可修改时也可以用来标志一个函数

即一个函数即使参数个数、类型全相等,但一个使用const修饰函数,一个没有,则这两个函数还是可以被定义的

左值形参和右值形参

首先区分传引用和传复制传值,如下这两个定义会出现重复定义

double cube(double& x);

double cube(double x);

左值形参和右值形参情况有所不同

假设有如下定义

double cube(double&& x)

double cube(double x)

使用cube(x)调用的时候调用第二个,但使用cube(x+1)时会出现多个匹配问题(匹配问题说明函数定义是没有歧义的,但是在寻找对应的匹配的函数是有多个符合条件的结果,只是不知道选哪个)

二、函数匹配问题

定义了一组重载函数后,我们需要以合理的实参调用它们。函数匹配是指一个过程,在这个过程中我们把函数调用与一组重载函数中的某一个关联起来,函数匹配也叫做函数确定。编译器首先将调用的实参与重载集合中每一个函数的形参进行比较,然后根据比较的结果决定到底调用哪个函数。

现在我们需要掌握的是,当调用重载函数时有三种可能的结果:

  • 编译器找到一个与实参最佳匹配的函数,并生成调用该函数的代码;
  • 找不到任何一个函数与调用的实参匹配,此时编译器发出无匹配的错误信息;
  • 又多于一个函数可以匹配,但是每一个都不是明显的最佳选择。此时也将发生错误,称为二义性调用。

函数匹配过程分为三步

1、   确定候选函数,候选函数具备两个特征:一是与被调用的函数同名,二是其声明在调用点可见。

2、   确定可行函数,可行函数也具备两个特征:一是形参数量与本次调用的形参数量一致,二是每个实参的类型与对应的形参类型相同,或者能转化成形参的类型

3、   寻找最佳匹配,有多个可行函数的时候,需要选择一个最佳匹配,基本思想是实参类型与形参类型越接近,他们匹配得越好。

含有多个参数的函数匹配,有且只有一个函数满足下列条件,函数匹配成功:

l  该函数每个实参匹配都不劣于其他可行函数需要的匹配

l  至少有一个实参的匹配优于其他可行函数的匹配

比如使用f(2,3.5)匹配下面函数时会出现冲突:

void f(int x,int y)

void f(double x, double y)

实参类型转换

编译器将实参到形参的转换划分为几个等级

1、  精确匹配,包含如下情况

l  实参与形参类型相同

l  实参从数组类型或函数类型转换成对应的指针类型

l  向实参添加顶层const或者从实参中删除顶层const

2、  通过const转换实现的匹配

3、  通过类型提升实现的转换

4、  通过算术类型(int、short等的转换)或指针转换(0或字面值nullptr能转换成任意指针类型,指向任意非常量的指针能转换成void*,指向任意对象的指针能转换成void*)

5、  通过类类型转换实现的匹配

区别类型的提升和转换:

把char、unsigned char、short、unsigned short转换成int类型称为类型提升(promotion)

long double、double、float、unsigned long long、long long、unsigned long、long、unsigned int、int之间的转换称为类型转换

类型等级由高到低依次为:long double、double、float、 unsigned long long、long long、unsigned long、long、unsigned int、int

区分“忽略顶层const”和“const转换”

忽略顶层const的例子,他们单独都可以被double x = 9.0;cube(x);两条语句调用(即使x是非const,但仍旧可以调用double cube(const double x)),所以以下两种是同一定义:

double cube(const double x)

double cube(double x)

看一个指针的例子,下面两种同样是忽略顶层const的例子。他们单独都可以被double x = 9.0;cube(x);两条语句调用:

double cube(double* x)

double cube( double* const x)

如果有double cube(const double x),同样可以使用以下语句调用,因为

double x = 9.0

cube(&x)

以上都是顶层冲突的例子,但是const转换不同,它指非const的对象能被转换成const

double cube(const double * x)

能被以下的语句调用

double x = 9.0

cube(&x)

x不是const的,但是传给了const,出现了const转换

c++选择重载函数的更多相关文章

  1. C++:成员运算符重载函数和友元运算符重载函数的比较

    5.2.4 成员运算符重载函数和友元运算符重载函数的比较 (1)对双目运算符而言,成员运算符重载函数参数表中含有一个参数,而友元运算符重载函数参数表中有两个参数:对于单目运算符而言,成员运算符重载函数 ...

  2. 你好,C++(28)用空间换时间 5.2 内联函数 5.3 重载函数

    5.2  内联函数 通过5.1节的学习我们知道,系统为了实现函数调用会做很多额外的幕后工作:保存现场.对参数进行赋值.恢复现场等等.如果函数在程序内被多次调用,且其本身比较短小,可以很快执行完毕,那么 ...

  3. C++学习笔记(十二):重载函数

    1. 什么是重载函数 假设同一作用域内的几个函数名字同样但形參列表不同.那么这些函数就称之为--重载函数. 比如: void print( const char *cp); void print(co ...

  4. Item 27: 明白什么时候选择重载,什么时候选择universal引用

    本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 Item 26已经解释了,不管是对全局函数还是成员 ...

  5. C++ 重载运算符和重载函数

    C++ 重载运算符和重载函数 C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是 ...

  6. C++解析七-重载运算符和重载函数

    重载运算符和重载函数C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载.重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列 ...

  7. C++ 基础语法 快速复习笔记(3)---重载函数,多态,虚函数

    1.重载运算符和重载函数: C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它 ...

  8. Matlab匿名函数,子函数,私有函数,重载函数,eval和feval函数

    匿名函数,子函数,私有函数等函数类型 匿名函数: 匿名函数没有函数名,也不是.m文件,只包含一个表达式和输入输出参数. Fxy=@(x,y)x.^y+3*x*y x,y为输入输入参数,Fxy为函数名 ...

  9. 吴裕雄--天生自然C++语言学习笔记:C++ 重载运算符和重载函数

    C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不 ...

随机推荐

  1. Java实现对文本文件MD5加密并ftp传送到远程主机目录

    需求描述: 客户出完账之后需要把出账的数据以文本文件的方式传送给收入管理系统,客户以前是通过本地的一个工具软件上传的,由于安全监管的原因,不允许在本地使用工具上传,因此客户希望我们在已经上线使用的系统 ...

  2. java(二)Web部分

    2.1.1讲一下http get和post请求的区别? GET和POST请求都是http的请求方式,用户通过不同的http的请求方式完成对资源(url)的不同操作.GET,POST,PUT,DELET ...

  3. Android中监控USB的插拔

    一.需求 在Android应该开发过程中,用到了USB通讯,需要应用监控USB设备的插入和拔出,从而刷新USB设备列表. 二.实现 在使用时,需要register和unregister. 通过UsbD ...

  4. git 团队开发常用操作流程(适用于 gogs、gitlab、github)

    git 团队开发常用操作流程(适用于 gogs.gitlab.github) NO1 项目构建者 (1)在远程仓库创建仓库 (2)将伙伴添加到仓库合作者中(无先后要求) (2)cd 到项目将要存放项目 ...

  5. 一套高可用、易伸缩、高并发的IM群聊架构方案设计实践

    本文原题为“一套高可用群聊消息系统实现”,由作者“于雨氏”授权整理和发布,内容有些许改动,作者博客地址:alexstocks.github.io.应作者要求,如需转载,请联系作者获得授权. 一.引言 ...

  6. Javascript高级编程学习笔记(71)—— 模拟事件(1)DOM事件模拟

    事件,指的是网页中某个特定的交互时刻 一般来说事件由浏览器厂商负责提供,一般由用户操作或者其它浏览器功能来触发 但是有一类特殊的事件,那就是由我们开发人员通过JS触发的事件 这些事件和浏览器创建的事件 ...

  7. Javascript高级编程学习笔记(38)—— DOM(4)Text

    Text类型 html页面中的纯文本内容就属于Text类型 纯文本内容可以包含转义后的html字符,但不能包括 html 代码 text类型具有以下属性.方法 nodeType:3 nodeName: ...

  8. Kali学习笔记13:操作系统识别

    为什么要扫描操作系统呢? 其实和上一篇博客:<服务扫描>类似,都是为了能够发现漏洞 发现什么漏洞? 不同的操作系统.相同操作系统不同版本,都存在着一些可以利用的漏洞 而且,不同的系统会默认 ...

  9. ubuntu16.04 uninstall cuda 9.0 completely and install 8.0 instead

    卸载cuda 9.0sudo apt-get --purge remove cudasudo apt autoremoveto remove cuda 9.0 Thensudo apt-get cle ...

  10. 【spring】从简单配置使用到深入

    一.使用前的配置 1.maven引入需要的jar包 <properties> <spring.version>4.1.6.RELEASE</spring.version& ...