C++再谈函数


函数我们在C的时候已经介绍清楚了,这里我们主要介绍C++新增加的特性。在C++概述那一个章节,我们简单介绍了函数,现在我们就详细介绍一下,例如引用作为函数值,函数返回值,函数的默认参数…



引用


1.引用简介


引用是C++提供的一个新的特性,在C++中也比较常用,能够正确操作使用引用,使我们的程序看起来比较简洁,也比较高效。


引用是给变量起一个别名,共享相同的内存区域。好比一个人拥有两个名字。


2.引用的定义

 

int a=0;
int &b=a;//b就成了a的别名,声明的时候必须定义


3.引用作为函数参数


大家在学习C的使用,肯定写过实现两个数据交换的函数,如下所示:我们采用的是传值的方式,只是改变了形参的值,实参是没有任何影响的。要让实参的值发生改变,我们有两种方式,传指针和传引用,传指针大家是比较熟悉的,这里我们就介绍传引用。


function1.png


更改代码如下:只是需要将需要改变实参的形参的传入改为引用传递。


function2.png


函数参数是否需要传引用的判别:


1)需要在函数内部改变实参的值;


2)函数传入值比较大,为避免拷贝的代价,使用引用 。


下面是一个很大的结构体,它的参数传递的拷贝是需要很多时间的,为了避免这种拷贝降低程序性能,我们就使用传引用。当然,如果你只是希望读取这个结构而不希望修改它,你可以将传入参数修改为const BigStruct &a;


function3.png


4.引用作为函数返回值


引用作为函数返回值的好处和作为函数参数的效果是一样的,这里我们返回的是一个不可以被修改的应用。引用的返回和指针的返回是有一定风险的,返回的这一个变量一定要是不能是一个仅在该函数内部可见的局部变量,这样的变量在退出函数的时候就被销毁了,无法返回它的地址,就会导致不可预知的错误。如果一定要返回,请保证返回的变量在这个函数之外一定也是可见的。


function4.png




函数的默认参数


我们在定义函数的时候,可以设置一些参数的值。我们在调用的时候,就可以省略这些参数的值,进而使用函数定义时候的默认值。


函数默认值的使用:


1.声明或者定义的时候为默认参数设置一个值;


2.调用的时候可以省略这些具有默认值的参数。


测试代码如下:这里一个函数里面的两个参数都有了默认值,第一个move调用的时候使用的是调用时候所赋的值,即step=2,dalta=40;


在调用时候给的参数不够的话,默认是先将函数里面左边的参数赋值,右边没有的参数使用默认值,即step=2,dalta=20;最后一个全部采用函数定义时候的默认值即step=1,dalta=20;


function5.png


测试代码如下:我们在一个函数中可以仅仅为需要默认参数的函数传入默认的值。


function6.png


注意


1)当一个参数被声明为默认参数,它后面所有的参数都要有默认值;


2)默认值指定仅限在声明或者定义的时候指定,只能在一个地方指定。



函数的重载


函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。参数列表不同包括参数类型和参数个数,两个其一不同就可以实现重载。


重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。我们也尽量不要把功能不同的函数定义为重载,这样可能会造成误用的。


注意:如果两个函数参数列表相同,仅仅是返回值不同,这不是重载,编译器在编译的时候会报错。


为什么需要重载呐?比如我们在cout的时候,不需要特别指定输出的参数是什么类型,编译器会自动识别它的类型,然后调用不同类型的输出函数。虽然以前我们不知道函数重载,但是我们一直在使用函数重载,例如加号运算符,我们使用它对整数和浮点数的加法运算…


下面我们通过代码来看一下add函数的重载:这里我们定义了三个add函数,分别对应了int,float,double类型的数的相加,调用的时候虽然都是一个函数名,但是在编译器具体调用哪一个函数的时候会依据函数的参数来调用。


function7.png



函数模板


函数的重载需要我们为每一个类型都添加一个add函数,函数模板就可以为我们省去多余的代码。我们只需要定义一个函数,就可以实现所有类型的调用。这就相当于一个函数模板,它会根据相应的参数来生成不同的函数,供这些参数来调用。


所谓函数模板,实际上是创建一个通用函数,其函数返回值类型和形参类型不具体指定,用一个虚拟的类型来代替。这个通用函数就称为函数模板。


函数模板的定义形式是:


template <typename Type1, typename Type2 > //可以包含多个数据类型


函数实现:通过调用来实例化出不同类型的函数,这个过程由编译器实现。


测试代码如下:T声明为一个虚拟的类型,它可以是系统预先定义好的类型,如int,float,还可以是我们自己定义的类等等..这个函数模板参数和返回值都是一个类型的,如果需要两个类型,你需要template <typename Type1, typename Type2 >这样来声明两个类型。当我们使用下面的代码调用的时候,编译器为我们自动生成该类型的add函数,经过下面两次的调用,它可以生成下边红框内的两个函数。当然,它还可以经过调用生成其它的函数。调用函数模板的函数调用的参数个数必须是一致的。


function8.png


与函数重载的比较


1)模板函数与函数重载有些类似,但不同之处也很明显。;


2)重载函数内部实现可以完全不同,但模板函数内部算法相同。


函数模板在平时使用的时候其实不是很常用的,与函数模板相比,我们更广泛使用的是类模板,类模板我们在后面会介绍。大家现在只是需要了解模板的定义,后面在介绍类模板的时候还会详细介绍模板的知识点。



【本文由麦子学院独家原创,转载请注明出处并保留原文链接】

logo
© 2012-2016 www.maiziedu.com
蜀ICP备13014270号-4 Version 5.0.0 release20160127

有一位课程导师想与你聊聊

客服热线 400-862-8862

回到顶部