C++——缺省参数、函数重载、引用、inline
一、缺省参数
(1)缺省参数是声明或定义函数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参,缺省参数分为全缺省和半缺省参数。(有些地方把缺省参数也叫默认参数)
#include <iostream>
#include<assert.h>
using namespace std;
void func(int a = 0)
{
cout << a << endl;
}
int main()
{
func();
func(10);
return 0;
}
(2) 全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。c++规定半缺省参数必须从左往右依次连续缺省不能间隔跳跃给缺省值。
如果没有从左到右那么就会报错
(3)函数声明和定义分离时,缺省参数不能再函数声明和定义中同时存在,规定函数声明给缺省值
(目的为了防止出现声明和定义同时给不同的缺省值,那么编译器并不知道选哪一个)
二、函数重载
C++支持在同一作用域中出现同名函数,但是要求这些同名函数的参数不同,可以是参数个数不同或者类型不同。这样C++函数就表现出了多态行为,使用更灵活。(C语言不支持同一作用域中出现同名函数)
(1)参数类型不同
(2)参数个数不同
(3)参数类型顺序不同
(4) 返回值不同不能作为条件
编译器不知道调用哪一个
三、引用
(1)引用的概念
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。比如:红楼梦的别名石头记。
(2)引用的格式
类型&引用=引用对象
(c++中为了避免引用太多的运算符,会使用c语言的一些符号,比如前面的《》,这里引用也和取地址使用了同一个符号&,大家注意区分)
此时b就是a的别名,它两的地址相同,如果b++那么a也++;
(3) 引用的特征
1.引用在初始化时必须初始化
因b未被初始化而报错
2.一个变量可以有多个引用
3.引用一旦引用一个实体,再不能引用其他实体
这时候b = d只是一个赋值而非引用。
(2) 引用的使用
引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被引用对象。
引用传参跟指针传参功能时类似的,引用传参相对跟方便一些。
引用返回值的场景相对比较复杂
引用和指针在实践中相辅相成,功能有重叠性,但是各有各的特点,互相不可代替
(3)const引用
1.可以引用const对象,但是必须用const引用。const引用也可以引用普通对象,因为对象的访问权限在引用中可以缩小,但是不能放大。
权限的放大
const 修饰的值不能改变,下图中a不能改变,但是他的别名b 不是const型的可以改变,所以权限放大了,造成权限放大
权限的缩小
上图中a可以改变,但b是const类型的不能改变,涉及到权限的缩小这是可以的。
权限的平移
上图中a 和b都是const型的,是权限的平移 。
2. 需要注意的是类似 int& r = a*3; double d = 3.14; int&a = d;这样一些场景下a*3的和结果存在一个临时对象中,int&a = d 也是类似,在类型转换中会产生临时对象存储中间值,也就是说r和a引用的都是临时对象,而C++规定临时对象具有常性,所以这里就触发了权限的放大,必须要用常引用才可以。(所谓临时变量就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象,C++中把这个未命名对象叫做临时对象)
(4)指针和引用的关系
语法概念上引用是一个变量的取别名不开空间(底层其实也开),指针是存储一个变量地址,要开空间。
引用在定义时必须初始化,指针建议初始化,但是语法上不是必须的。
引用在初始化时引用一个对象后,就不能在引用其他对象;而指针可以不断地改变指向对象
引用可以直接访问对象,指针需要解引用才能访问指向对象。
sizeof中含义不同,引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位下是8字节)
指针容易出现空指针和野指针的问题,引用很少出现,引用使用相对更安全。
四、inline
(1)inline的定义
用inline修饰的函数叫做内联函数,编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数就不需要建立栈帧从而提升效率。
(2)inline的注意事项
inline对于编译器而言只是一个建议,也就是说,你加了inline编译器也可以选在调用的地方不展开,不同的编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline使用于频繁调用的短小函数,对于递归函数,代码相对于多一些的函数,加上inline也会被编译器忽略
vs编译器debug版本下面默认是不展开inline的,这样方便调试,debug版本想展开需要设置一下