C++中的引用和const引用详解(重点研究引用作返回值和参数时的情况)

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引用,需要改变值时用引用

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
constconstexpr是C语言用于定义常量的两个关键字。 const是一个修饰符,用于声明一个不可改变的常量。在C语言,我们可以使用const来定义一个常量,一旦被定义后,就不能再改变其值。常量一般用大写字母表示,例如: ``` const int MAX_VALUE = 100; ``` 在上述代码,MAX_VALUE被定义为一个常量,其值为100,这意味着在程序的其他地方不能再改变MAX_VALUE的值。 constexpr是C++11新增加的关键字,用于在编译求得表达式的值,并将其为一个常量。与const类似,constexpr也用于定义常量,但它的需求更加严格。在C++constexpr可以用于常量的定义、函数的参数返回值等。 constexpr的特点是在编译求值,因此可以提高程序的运行效率。例如: ``` constexpr int square(int x) { return x * x; } int main() { constexpr int num = 5; constexpr int result = square(num); return 0; } ``` 在上述代码,我们定义了一个constexpr函数square,它接收一个参数x,并返回x的平方。在main函数,我们使用constexpr定义了一个常量num,并将它为square函数的参数,得到了一个常量result。 总结来说,constconstexpr都是用于定义常量的关键字。const适用于C语言,用于声明不可改变的常量;constexpr适用于C++11及以后的版本,用于在编译求得表达式的值,并将其为一个常量。在实际的开发,根据具体的需求来选择使用const还是constexpr。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一镜花水月一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值