文章目录
1.为什么要引入引用
当人们在总结C语言的经验教训时,为了对C语言指针导致内存溢出的问题进行改进,因此在C++引入了引用类型。当使用指针时,我们需要手动管理内存分配和释放,容易出现内存泄漏的问题,而使用引用可以避免这些问题,因为引用并不需要分配和释放内存,而且在大部分情况能够替代指针。
2.引用的基本语法
普通引用
int a = 1;
int& b = a;//b是a的别名,b就是a;
引用更接近于const指针:必须在创建时初始化,而且一旦于某个变量相关联就一直效忠于它(int * const p = &a)。
多重引用
int a = 1;
int& b = a;
int& c = b;
多重引用其实就是给这个变量取很多别名,a有b和c两个别名
const引用
int a = 1;
const int& b = a;
不能通过b去改变a的值。
3.const的基本语法
直介绍和指针的搭配用法。
如果const位于*的左侧,则const修饰变量;
如果const位于*的右侧,则const修饰指针;
const char * a; // 指向const对象的指针或者说指向常量的指针。
char const * a; // 同上
char * const a; // 指向类型对象的const指针。或者说常指针、const指针。
const char * const a; // 指向const对象的const指针。
4.引用作为函数参数
函数的形参和实参的传递过程
void func(int x);
int a = 1;
func(a);
参数传递时,其实是执行了int x = a的语句。
普通引用作为函数参数
void func(int& x);
int a = 1;
func(a);
参数传递时,其实是执行了int& x = a的语句,因此对a改变相当于对x进行改变;
因此引用传递能把形参和实参挂钩。
const引用作为函数参数
void func(const int& x);
int a = 1;
func(a);
相当于const int& x = a;
相较于值传递它的优点在于:当使用值传递时,会将参数的副本传递给被调用函数,这意味着会进行一次拷贝操作。对于较大的对象或数据结构,拷贝操作可能会影响性能。而使用const引用传递,只需要传递对象的引用,不会进行拷贝操作,因此可以提高性能。相较于普通引用传递它的优点在于:它可以防止函数对实参进行修改;因此const引用实际上既具有安全性又具有高性能
5.引用作为函数返回值
函数返回值的传递过程
int func(int x)
{
return x;
}
int a = 1;
int b = func(a);
int b = func(a)语句执行的步骤是:
1.先进行参数传递int x = a;
2.再执行return语句,这里return给谁了呢,其实是return给一个临时变量temp,即相当于执行语句
int temp = x;
3.由于函数执行完毕,局部变量x的内存被释放,但temp保存了x的值;
4.int b = temp;
也就是说,虽然func(a)、temp和x三个的值相等,但在函数执行完毕后,x内存被释放了;
那么由于这个特性,引用作为返回值时会有很大的风险,下面介绍。
引用作为函数返回值
int& func(int x)
{
return x;
}
int a = 1;
int& b = func(a);
当func(a)执行完毕后,是实际上执行了int x = a和int& temp = x;
然后再执行int& b = temp;
由多重引用可以得知,实际上是对局部变量x取了b和temp两个别名,而x是已经被释放的内存,
具有极大的安全隐患;
因此引用作为函数返回值时,应该return函数参数中的引用类型参数,来避免这种危险;
int& func(int& x)
{
return x;
}
int a = 1;
int& b = func(a);
该函数执行流程:
int& x = a;
int&temp = x;
int& b = temp;
相当于给a取了x、temp和b3个别名。
它的优点也是可以提高性能。
const引用作为函数返回值
防止返回值被接收的变量改变
const int& func(int& x)
{
return x;
}
int a = 1;
const int& b = func(a);
相当于给a取了x、temp和b3个别名,而x被释放,temp不能显示调用,b又是const,因此要想改变a的值只能通过调用a来改变。
6.什么时候用指针传递,什么时候用引用传递,什么时候值传递
对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void func(int x) 不应该改为void func(const int &x)。因此对于基本数据类型(int、short、long、long long、float、double、char、bool)这种小结构,在不需要改变值时用值传递,需要改变值时用指针;
数组这种结构无法使用引用,只能用指针,因此数组在不需要改变值时用指向const的指针,需要改变值时用指针;
对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。例如将void func(A a) 改为void func(const A &a)。因此类对象和结构在不需要改变值时用const引用,需要改变值时用引用;