1.引用
引用必须初始化
一个变量可以有多个别名
引用一旦引用一个实体,再不能引用其他实体
注意: 引用不能替代指针,引用不能改变指向。(实质就是取别名)
1.1 引用场景
①减少拷贝,提高效率。(减少拷贝临时对象,返回的是别名)
②引用传参更加方便。(与指针传参类似)
③引用和指针不可相互替代。
④C++中引用不能改变指向,Java中的引用可以改变指向(这里不做具体的介绍)。
①和②示例
void Swap(int& rx, int& ry)
{int tmp = rx;rx = ry;ry = tmp;
}int main()
{int x = 0, y = 1;cout << x << " " << y << endl;Swap(x, y);cout << x << " " << y << endl;return 0;
}
注意:越界读不一定会报错。(一般是抽查)
1.2 const 引用
①可以引用一个const对象,但是必须用const引用。(权限可以缩小,但是不能放大)
②C++规定临时对象具有常性。
③引用对象可以是:const对象,临时对象,普通对象。
①的示例
int main()
{const int a = 10;//int& ra = a;//此时是错误的,因为a不能修改,别名也不能修改a 的值//相当于权限放大const int& ra = a;int b = 1;const int& rb = b;//此时是正确的,相当于权限缩小return 0;
}
②示例:
int main()
{int a = 10;//int& rb = a * 3;//这里是错误的//a * 3会被存储在一个临时对象中,而C++规定临时对象具有常性。double d = 12.34;int rd = d;double d = 13.14;const int& rd = d;//中间也会产生临时对象,临时对象为Int类型return 0;
}
1.3 引用和指针的关系
①引用是取别名,不开空间;指针要开空间。
②引用必须初始化;指针不要求。
③引用初始化引用时不能引用其他的对象;指针不做要求。
④引用可以直接访问对象。
⑤引用是一个类型;指针始终是一个地址。
⑥指针最容易出现野指针。
2.inline
①inline修饰的函数叫做内联函数,可以提高效率。(编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数就不需要建立栈帧了,就可以提高效率。)
②inline只是一个建议,短小函数会展开。
③C++使用inline 来替代宏函数。
④vs编译器debug版本下面默认是不展开inline的,这样方便调试,debug版本想展开需要进行设置。
⑤不建议分成两个文件。
正确宏的写法示例:
#define ADD(a, b) ((a) + (b))
(宏函数坑很多,但是替换机制,调用时不用建立栈帧,可以提升效果)
inline 使用示例:
//inline 没有宏函数的坑,也不用建立栈帧,可以提效.
inline int ADD(int x, int y)
{int ret = x + y;return ret;
}
int main()
{int x = 1, y = 2;ADD(x & y, x | y);return 0;
}
(函数被编译以后是一堆指令,需要存储起来执行;第一句指令的地址就是函数的地址)
3.nullptr
NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:
C++中定义为0
①特殊的关键字,可以转成任意类型的指针变量。
②使用nullptr定义空指针可以避免类型转换的问题。
③nullptr只能被隐式转换为指针类型,而不能转换为整数类型。