c++学习笔记之函数重载和模板理解
1、函数重载:
C++ 不允许变量重名,但是允许多个函数取相同的名字,只要参数表不同即可,这叫作函数的重载(其英文是 overload)。重载就是装载多种东西的意思,即同一个事物能完成不同功能。
所谓重载,就是赋予新的含义。函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作。运算符重载(Operator Overloading)也是一个道理,同一个运算符可以有不同的功能。
函数的重载使得 C++ 程序员对完成类似功能的不同函数可以统一命名,减少了命名所花的心思。例如,可能会需要一个求两个整数的最大值的函数,也可能还要写一个求三个实数的最大值的函数,这两个函数的功能都是求最大值,那么就都命名为 Max 即可,不需要一个命名为 MaxOfTwoIntegers,另一个命名为 MaxOfThreeFloats。如下:
#include <iostream>
using namespace std;
void Max(int a, int b)
{
cout << "Max 1" << endl;
}
void Max(double a, double b)
{
cout << "Max 2" << endl;
}
void Max(double a, double b, double c)
{
cout << "Max 3" << endl;
}
int main()
{
Max(, ); //调用 int Max(int, int)
Max(2.4, 6.0); //调用 double Max(doubleA double)
Max(1.2, 3.4, ); //调用 double Max(double, double, double)
Max(, , ); //调用 double Max(double, double, double)
Max(, 1.5); //编译出错:二义性
return ;
}
再如:
#include <iostream>
using namespace std; //交换 int 变量的值
void Swap(int *a, int *b){
int temp = *a;
*a = *b;
*b = temp;
} //交换 float 变量的值
void Swap(float *a, float *b){
float temp = *a;
*a = *b;
*b = temp;
} //交换 char 变量的值
void Swap(char *a, char *b){
char temp = *a;
*a = *b;
*b = temp;
} //交换 bool 变量的值
void Swap(bool *a, bool *b){
char temp = *a;
*a = *b;
*b = temp;
} int main(){
//交换 int 变量的值
int n1 = , n2 = ;
Swap(&n1, &n2);
cout<<n1<<", "<<n2<<endl; //交换 float 变量的值
float f1 = 12.5, f2 = 56.93;
Swap(&f1, &f2);
cout<<f1<<", "<<f2<<endl; //交换 char 变量的值
char c1 = 'A', c2 = 'B';
Swap(&c1, &c2);
cout<<c1<<", "<<c2<<endl; //交换 bool 变量的值
bool b1 = false, b2 = true;
Swap(&b1, &b2);
cout<<b1<<", "<<b2<<endl; return ;
}
运行结果:
,
56.93, 12.5
B, A
,
这些函数虽然在调用时方便了一些,但从本质上说还是定义了三个功能相同、函数体相同的函数,只是数据的类型不同而已,这看起来有点浪费代码,能不能把它们压缩成一个函数呢?
能!可以借助本节讲的函数模板。
2、在C++中,数据的类型也可以通过参数来传递,在函数定义时可以不指明具体的数据类型,当发生函数调用时,编译器可以根据传入的实参自动推断数据类型。这就是类型的参数化。
值(Value)和类型(Type)是数据的两个主要特征,它们在C++中都可以被参数化。
所谓函数模板,实际上是建立一个通用函数,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据传入的实参来逆推出真正的类型。这个通用函数就称为函数模板(Function Template)。
在函数模板中,数据的值和类型都被参数化了,发生函数调用时编译器会根据传入的实参来推演形参的值和类型。换个角度说,函数模板除了支持值的参数化,还支持类型的参数化。
一但定义了函数模板,就可以将类型参数用于函数定义和函数声明了。说得直白一点,原来使用 int、float、char 等内置类型的地方,都可以用类型参数来代替。
下面我们就来实践一下,将上面的四个Swap() 函数压缩为一个函数模板:
#include<iostream>
using namespace std; template<typename T> void Swap(T *a,T *b){ //交换函数模板
T temp=*a;
*a=*b;
*b=temp;
} int main(void){
//交换 int 变量的值
int n1=;
int n2=;
Swap(&n1,&n2);
cout<<n1<<", "<<n2<<endl; //交换 float 变量的值
float f1 = 12.5, f2 = 56.93;
Swap(&f1, &f2);
cout<<f1<<", "<<f2<<endl;
return ;
}
运行结果:
,
56.93, 12.5
template是定义函数模板的关键字,它后面紧跟尖括号<>,尖括号包围的是类型参数(也可以说是虚拟的类型,或者说是类型占位符)。typename是另外一个关键字,用来声明具体的类型参数,这里的类型参数就是 T。从整体上看,template<typename T>被称为模板头。
模板头中包含的类型参数可以用在函数定义的各个位置,包括返回值、形参列表和函数体;本例我们在形参列表和函数体中使用了类型参数T。
类型参数的命名规则跟其他标识符的命名规则一样,不过使用 T、T1、T2、Type 等已经成为了一种惯例。
c++学习笔记之函数重载和模板理解的更多相关文章
- 【C#学习笔记】函数重载
using System; namespace ConsoleApplication { class Program { static void Print(int a, int b) { Conso ...
- C++基础 学习笔记五:重载之运算符重载
C++基础 学习笔记五:重载之运算符重载 什么是运算符重载 用同一个运算符完成不同的功能即同一个运算符可以有不同的功能的方法叫做运算符重载.运算符重载是静态多态性的体现. 运算符重载的规则 重载公式 ...
- Matlab学习笔记 figure函数
Matlab学习笔记 figure函数 matlab中的 figure 命令,能够创建一个用来显示图形输出的一个窗口对象.每一个这样的窗口都有一些属性,例如窗口的尺寸.位置,等等.下面一一介绍它们. ...
- matlab学习笔记 bsxfun函数
matlab学习笔记 bsxfun函数 最近总是遇到 bsxfun这个函数,前几次因为无关紧要只是大概看了一下函数体去对比结果,今天再一次遇见了这个函数,想想还是有必要掌握的,遂查了些资料总结如下. ...
- matlab学习笔记13_1 函数返回值
一起来学matlab-matlab学习笔记13函数 13_1 函数返回值 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 https://blog.csdn.net/qq_36556 ...
- C++学习笔记2_函数.函数指针.函数模板
1. 内联函数void printAB(int a,int b){ cout<<(a)<<(b)<<endl;}int main(void){ for(int i= ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 重载运算符和重载函数
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不 ...
- C++学习笔记之运算符重载
一.运算符重载基本知识 在前面的一篇博文 C++学习笔记之模板(1)——从函数重载到函数模板 中,介绍了函数重载的概念,定义及用法,函数重载(也被称之为函数多态)就是使用户能够定义多个名称相同但特征标 ...
- swift学习笔记2——函数、闭包
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
随机推荐
- 日期与时间(C/C++)
C++继承了C语言用于日期和时间操作的结构和函数,使用之前程序要引用<ctime>头文件 有四个与时间相关的类型:clock_t.time_t.size_t.和tm.类型clock_t.s ...
- 想学习linux操作系统,于是选择了在win8 虚拟机VM player 里装了Linux版本Centos7
第一次接触linux,第一次玩linux的命令行哈. 以下python使用的都是自带的python2.x版本 先新建一个简单的文件夹py_studydir 新建该文件夹下面的一个py文件 写入pyth ...
- Hdu2037
Hdu2037 - 今年暑假不AC 题意: 在一个数轴上有n条线段,现要选取其中k条线段使得这k条线段两两没有重合部分,问最大的k为多少. 解法: 这其实就是一个大水题,一个非常简单明了的区间覆盖问题 ...
- Namenode服务挂
BUG修复:HDFS-13112 这两天排查了小集群Crash的问题,这里先总结下这两天排查的结果 一.查看日志 首先查看了Namenode Crash的时候的日志 (一)以下是patch hdfs- ...
- impala 四舍五入后转换成string后又变成一个double的数值解决(除不尽的情况)
impala 四舍五入后转换成string后又变成一个double的数值解决(除不尽的情况)例如Query: select cast(round(2 / 3, 4)*100 as string)+-- ...
- docker容器安装命令
apt-get update apt-get install vim 转载请注明博客出处:http://www.cnblogs.com/cjh-notes/
- how to force git to overwritten local files
最佳解决方法 重要提示:如果您有任何本地更改,将会丢失.无论是否有--hard选项,任何未被推送的本地提交都将丢失. 如果您有任何未被Git跟踪的文件(例如上传的用户内容),这些文件将不会受到影响. ...
- RecyclerView只有一行
RecyclerView只有一行 方法1: 将RecyclerView放在父容器RelativeLayout中,并设置RelativeLayout属性 android:descendantFocu ...
- Springboot整合 mybatis-generator
1.pom.xml文件中 生成依赖 <plugin> <groupId>org.mybatis.generator</groupId> <artifactId ...
- ART模式
ART模式是Android RunTime的简称,自动对程序进行代码预读取编译,让程序直接编译成机器语言,免去了Dalvik模式要时时转换代码,实现高效率.省电.占用更低的系统内存.手机运行流畅.但凡 ...