C++中的函数重载分析(一)
1,重载是 C 语言到 C++ 语言的一个飞跃,C 语言中没有重载的概念,所有的函数 名是不允许有重复的,在 C++ 中因为引进了重载,所以函数名可以重复;
2,自然语言中的上下文:

1,你知道上面词汇中“洗”字的含义吗?
1,不同的动词和名次搭配的含义是不同的;
2,结论:
1,能和“洗”字搭配的词汇有很多;
2,“洗”字和不同的词汇搭配有不同的含义;
3,重载(Overload)的概念:
1,重载是同一个标识符在不同的上下文有不同的意义;
2,如:
1,“洗”和不同的词汇搭配后有不同的含义;
1,洗衣服,洗脸,洗脑,洗马桶,...;
2,“play”和不同的单词搭配后有不同的含义;
1,play chess, play piano, play basketball, ...;
4,思考:
1,重载在自然语言中是随处可见的,那么程序设计中是否也有重载呢?
1,让程序设计语言接近自然语言,所以计算机科学家在设计语言的时候就考虑将人类的语言习惯引进到程序设计语言中,C++ 就引入了重载的概念;
2,程序设计语言中和动词接近的是函数,所以 C++ 中选择函数来实现重载的概念;
5,C++ 中的函数重载:
1,函数重载(Function Overload):
1,用同一个函数名定义不同的函数;
1,这是 C++ 中重载的概念;
2,C++ 后续语言也是这样实现重载;
2,当函数名和不同的参数搭配时函数的含义不同;
1,当函数名和不同的参数搭配时实现了函数重载;
1,函数名类似动词,参数类似名词;
2,含义的不同在于所执行的函数体不同;
3,代码示例:
int func(int x)
{
return x;
} int func(int a, int b)
{
return a + b;
} int func(const char* s)
{
return strlen(s);
}
2,函数重载初探编程实验:
1,main.cpp 文件:
#include <stdio.h>
#include <string.h> int func(int x)
{
return x;
} int func(int a, int b)
{
return a + b;
} int func(const char* s)
{
return strlen(s);
} int main(int argc, char *argv[])
{
printf("%d\n", func());
printf("%d\n", func(, ));
printf("%d\n", func("D.T.Software")); return ;
}
2,输出结果:
3
9
12.
3,C++ 支持函数重载,它是根据自然语言中的重载概念得来的;
6,函数重载至少满足下面一个条件(数类序):
1,参数个数不同;
2,参数类型不同;
3,参数顺序不同;
7,当函数默认参数遇上函数重载会发生什么?
1,代码示例:
int func(int a, int b, int c = )
{
return a * b * c;
} int func(int a, int b) // 个数不同,构成重载;
{
return a + b;
} int main()
{
int c = func(, ); // which one? return ;
}
8,函数默认参数 VS 函数重载编程实验:
1,main.cpp 文件:
#include <stdio.h> int func(int a, int b, int c = )
{
return a * b * c;
} int func(int a, int b)
{
return a + b;
} int main(int argc, char *argv[])
{
int c = func(, ); // error: call of overloaded 'func(int, int)' is ambiguous return ;
}
2,这里是 C++ 中第一个特性冲突,后续 Java、C# 语言上述的默认参数值是不允许的,因为程序设计时,不允许二义性;
9,编译器调用重载函数的准则:
1,将所有同名函数作为候选者;
2,尝试寻找可行的候选函数;
1,精确匹配实参;
2,通过默认参数能够匹配实参;
3,通过默认类型转换匹配实参;
3,匹配失败:
1,最终寻找到的候选函数不唯一,则出现二义性,编译失败;
2,无法匹配所有候选者,函数未定义,编译失败;
10,函数重载的注意事项:
1,重载函数在本质上是相互独立的不同函数;
2,重载函数的函数类型不同;
3,函数返回值不能作为重载的依据;
1,函数重载是由函数名和参数列表决定的;
11,函数重载的本质编程实验:
1,main.cpp 文件:
#include <stdio.h> int add(int a, int b) // 函数类型为 int(int, int);
{
return a + b;
} int add(int a, int b, int c) // 函数类型为 int(int, int, int);
{
return a + b + c;
} int main()
{
printf("%p\n", (int(*)(int, int))add);//函数名 add 是函数入口地址,当只用add来得到地址时,由于重载的原因,编译器在此处显示 error: overloaded function with no contextual information,而当不是重载的函数时,可以直接使用 add 来获取函数地址;这里通过强制类型转换将 add 转换为 (int(*)(int, int)) 这样的函数指针;
printf("%p\n", (int(*)(int, int, int))add); return ;
}
2,输出结果:
00DF100A
00DF100F
3,结论 1:
1,函数的入口地址不同,可以反向的证明这是两个不同的函数;
4,通过 VS 命令行运行命令“dumpbin /symbols ProgramName.obj路径”查看 VS 中的工程符号表中的如下两行:
00E 00000000 SECT3 notype () External | ?add@@YAHHH@Z (int __cdecl add(int,int))
1,C++ 编译器编译 int __cdecl add(int,int) 函数后,在符号表中认为标识符为 ?add@@YAHHH@Z;
01F 00000000 SECT7 notype () External | ?add@@YAHHHH@Z (int __cdecl add(int,int,int))
1,C++ 编译器编译 int __cdecl add(int,int,int) 函数后,在符号表中认为标识符为 ?add@@YAHHHH@Z;
5,结论 2:
1,编译器在编译这两个函数的时候,已经分开对待了,编译器获得的这两个函数的名字是不同的;
2,编译器认为这是两个不同的函数,所以编译出的最终结果也就是可执行程序中这两个函数的入口地址是不同的;
6,总的结论:
1,不管正向推还是反向推,C++ 语言中重载函数的本质其实是不同的函数;
12,小结:
1,函数重载是 C++ 中引入的概念;
2,函数重载用于模拟自然语言中的词汇搭配;
3,函数重载使得 C++ 具有更丰富的语义表达能力;
1,让 C++ 编程更符合人类思维习惯;
4,函数重载的本质为相互独立的不同函数;
5,C++ 中通过函数名和函数参数确定函数调用;
1,返回值不参与重载过程;
C++中的函数重载分析(一)的更多相关文章
- C++中的函数重载分析(二)
1,重载与指针: 1,下面的函数指针将保存哪个函数的地址? int func(int x) { return x; } int func(int a, int b) { return a + b; } ...
- Oracle 中 decode 函数用法
Oracle 中 decode 函数用法 含义解释:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下:IF 条件=值1 THEN RETURN(翻译 ...
- mysql中now()函数的使用,还有oracle的sysdate,可能埋下的坑
mysql中now()函数的使用,还有oracle的sysdate 在需求中如果系统中药添加当前操作的时间那么很简单的一个操作在写sql的时候直接在这个字段对应的位置写上now()函数就可以了,这样就 ...
- 程序代码中退出函数exit()与返回函数return ()的区别
程序代码中退出函数exit()与返回函数return ()的区别 exit(0):正常运行程序并退出程序: exit(1):非正常运行导致退出程序: return():返回函数,若在主函数 ...
- mysql中find_in_set()函数的使用
首先举个例子来说: 有个文章表里面有个type字段,它存储的是文章类型,有 1头条.2推荐.3热点.4图文等等 .现在有篇文章他既是头条,又是热点,还是图文,type中以 1,3,4 的格式存储.那我 ...
- QT中使用函数指针
想仿命令行,所以定义了一个类,让一个String 对应一个 function,将两者输入list容器. 类中定义了 QString commandStr; void (MainWindow::*com ...
- Bash 是如何从环境变量中导入函数的
在上文中曾说到: 所谓的环境变量的真实面目其实就是个任意字符串 Bash 在启动时会将 environ 数组中包含 = 号的字符串导入成为自己的变量 Bash 在启动外部命令时会将自己内部标记为环境变 ...
- JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解
二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...
- PHP中spl_autoload_register()函数的用法
spl_autoload_register (PHP 5 >= 5.1.2) spl_autoload_register — 注册__autoload()函数 说明 bool spl_autol ...
随机推荐
- Vue组件创建和组件传值
Vue创建组件的方式 使用Vue.Extend()和Vue.component全局注册组件 首先我们定义一个组件并接收 var com1 =Vue.extend({ template:"&l ...
- html br标签 语法
html br标签 语法 br标签什么意思? 作用:插入一个简单的换行符.广州大理石机械构件 说明:<br> 标签是空标签(意味着它没有结束标签,因此这是错误的:<br>< ...
- 实战build-react(四)一个模块的进化过程
主框架结构 home/index.js //模块主文件 创建Topic模块 阶段一 基础代码 import React, { Component } from 'react'; import ...
- java开发需掌握技能2
1.了解Dubbo+Zookeeper面向服务SOA架构.SpringCloud+Eureka微服务架构.ActiveMQ消息通讯模式.RocketMQ分布式消息.Zookeeper集群.Redis缓 ...
- 2018-2019-2 20165235《网络对抗技术》Exp8 Web基础
2018-2019-2 20165235<网络对抗技术>Exp8 Web基础 实践过程记录: (1).Web前端HTML 能正常安装.启停Apache.理解HTML,理解表单,理解GET与 ...
- Make jQuery throw error when it doesn't match an element
Make jQuery throw error when it doesn't match an element 解答1 You could make a plugin to use to ensur ...
- js实现两个从input获取到的数字相加引发的问题
从input中获取到的数据是文本类型的,如果不转化类型直接相加会变成字符串的相加. 使用Number()函数可以解决这个问题,如下 var c = Number(a) + Number(b)
- Eigen中的矩阵及向量运算
Eigen中的矩阵及向量运算 ,[+,+=,-,-=] ,[\*,\*=] ,[.transpose()] ,[.dot(),.cross(),.adjoint()] ,针对矩阵元素进行的操作[.su ...
- linux配置ssh公钥认证,打通root用户的免密码输入的scp通道
1.ssh-keygen ssh-keygen是unix-like系统的一个用来生成.管理ssh公钥和私钥的工具. 2.用法 常用的重要的选项有: -b num 指定生成多少比特长度的key,单位 ...
- 分布式任务队列 Celery —— 应用基础
目录 目录 前文列表 前言 Celery 的周期定时任务 Celery 的同步调用 Celery 结果储存 Celery 的监控 Celery 的调试 前文列表 分布式任务队列 Celery 分布式任 ...