1. const引用
- const可以引用const(常量)对象,也可以引用普通对象,如int、double对象等。在引用访问的过程中,其权限可以被缩小,但是不能被放大。(权限放大是指:具有常性的对象(const修饰的对象或者临时对象等),对它们我们只能有读取访问的权限,并没有修改的权限。要是我们不加const来修饰这个引用,那么就表明我们可以通过这个引用来修改引用对象的值,这显然是不可以的)
- 要注意,C++规定:临时对象具有常性,所以必须使用const引用。在这里,a*3的值被储存在了一个临时对象里面。而身为double类型的b被取了个int类型的别名,进行了类型转换,而类型转换也是将转换后的值储存在临时对象里面的,所以综上,两个都要用const来修饰。
- 临时对象就是编译器需要一块空间将表达式计算得出的值储存在一个未命名的临时创建的空间里,C++管这叫临时对象。
int main()
{
int a = 10;
double b = 3.141;
//错误的引用(因为权限被放大)
int& ra = a*3;
int& rb = b;
//正确的引用
const int& va = a * 3;
const int& vb = b;
return 0;
}
2.inline
- 用inline修饰的函数叫做内联函数,编译时C++编译器会在调用的地方展开内联函数,不需要建立栈帧,从而提高了效率。
- 我们使用inline去修饰函数对于编译器来说只是一个建议,编译器不一定会将每个内联函数都在调用的地方进行展开,这取决于编译器,C++标准并没有规定。inline适用于修饰短小的,调用频繁的函数,而递归函数、代码量较大的函数,编译器会将inline忽略。
- 在C语言中有宏函数,在预处理的时候会替换展开,但是宏函数的实现很复杂很容易出错,并且不方便调试,C++就设计了内联函数来将其替代。
- inline不建议将定义和声明分离开到不同文件,因为在编译过程中内联函数展开就没有地址了,这样会导致链接失败。
- 在dubug版本下想要调试内联函数需要进行几个步骤才能调试。
3.nullptr
NULL其实是一个宏,在C的头文件(stddef.h)里有
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
这里我们可以看到NULL在C++环境下是0,在C的环境下就是空指针void*
- C++中NULL可能被定义为字⾯常量0,或者C中被定义为⽆类型指针(void*)的常量。不论采取何种定义,在使⽤空值的指针时,都不可避免的会遇到⼀些⿇烦,本想通过f(NULL)调⽤指针版本的f(int*)函数,但是由于NULL被定义成0,调⽤了f(int x),因此与程序的初衷相悖。f((void*)NULL);调⽤会报错。
- C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,⽽不能被转换为整数类型。