C++ 右值引用与 const 关键字详解

 更新时间:2022年10月08日 08:26:31   作者:木三百川  
C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,const关键字是一种修饰符,这篇文章主要介绍了C++ 右值引用与 const 关键字,需要的朋友可以参考下

C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,const关键字是一种修饰符。修饰符本身,并不产生任何实际代码。就 const 修饰符而言,它用来告诉编译器,被修饰的这些东西,具有只读的特点。在编译的过程中,一旦我们的代码试图去改变这些东西,编译器就应该给出错误提示。

C++11 新增了另一种引用:右值引用(rvalue reference),这种引用可指向右值,是使用 && 声明的。使用右值引用可以减少复制操作,延长临时对象生命周期,提升程序性能。它一般被用来实现移动语义和完美转发,将 const 关键字用于右值引用的场景不多,这里来总结一下 const 右值引用的特性,对其是否具有实际应用价值不做讨论。右值引用必须在创建的同时进行初始化,且只能使用右值进行初始化,可将 const 关键字用于右值引用,如下所示。

C++11 新增了另一种引用:右值引用(rvalue reference),这种引用可指向右值,是使用 && 声明的。使用右值引用可以减少复制操作,延长临时对象生命周期,提升程序性能。它一般被用来实现移动语义和完美转发,将 const 关键字用于右值引用的场景不多,这里来总结一下 const 右值引用的特性,对其是否具有实际应用价值不做讨论。右值引用必须在创建的同时进行初始化,且只能使用右值进行初始化,可将 const 关键字用于右值引用,如下所示:

//声明并初始化常规右值引用变量
int && rrx = 55;
 
//将const关键字用于右值引用变量,以下几种为等效表示
const int && crrx = 55;
int const && crrx = 55;

在 Microsoft Visual Studio 中连续多个 const 会被编译器解释成一个,即 const const const const int &&const int && 等效,除此之外,const int const && 在 Microsoft Visual Studio 中也与 const int && 等效,而 int && const 在 QT minGW 中将会报错,在 Microsoft Visual Studio 中与 int && 等效。

常规右值引用与 const 右值引用的特性如下:

  • 类型为 int && 的引用只能用来引用右值,不能用来引用左值,后面可修改其值。可将类型为 int 的非左值(比如字面常量 100、多项表达式 1+50*2、函数的 int 返回值)、类型不是 int 但可转换为 int 的非左值(比如多项表达式 1.0+50.0*2.0、字面常量 100.0、函数的 double 返回值)在初始化时赋给 rrx。变量初始化完成后,其地址就固定不变,其表现与 int 类型变量一致,右值引用变量自身属于左值。
  • 类型为 const int && 的引用也只能用来引用右值,不能用来引用左值,但后面不可修改其值。可将类型为 int 的非左值(比如字面常量 100、多项表达式 1+50*2、函数的 int 返回值)、类型不是 int 但可转换为 int 的非左值(比如多项表达式 1.0+50.0*2.0、字面常量 100.0、函数的 double 返回值)在初始化时赋给 crrx。变量初始化完成后,其地址就固定不变,其表现与 const int 类型变量一致,自身也属于左值。

常规右值引用变量的初始化用法如下:

//初始化方式一:字面常量
int && rrx = 100;
int && rrx = 100.0;
 
//初始化方式二:多项表达式
int && rrx = 1+50*2;
int && rrx = 1.0+50.0*2.0;
 
//初始化方式二:函数返回值
int && rrx = abs(10);
int && rrx = sqrt(10.0);

右值引用在部分情况下会生成临时变量(一个典型例子是使用字面常量右值如 100 来初始化右值引用变量),然后将右值引用变量作为该临时变量的别名,这与 const 左值引用十分相似,但与之不同的是:const 左值引用变量初始化完成后其值就无法被修改(权限为只读),右值引用变量初始化完成后其值仍可修改(权限为可读可写)。在另一些情况下,右值引用可以延长已有临时变量的生命周期,减少复制操作的次数(一个典型例子是使用函数返回的类对象来初始化右值引用变量,在关闭编译器优化的情况下可以将本需 2 次的复制操作减少为 1 次)。

const 关键字修饰的右值引用变量初始化用法如下,与常规右值引用变量的区别仅在于它们的可修改属性不同。

//初始化方式一:字面常量
const int && crrx = 100;
const int && crrx = 100.0;
 
//初始化方式二:多项表达式
const int && crrx = 1+50*2;
const int && crrx = 1.0+50.0*2.0;
 
//初始化方式二:函数返回值
const int && crrx = abs(10);
const int && crrx = sqrt(10.0);

将初始化时 int &&const int && 可接受的形式列个表,如下,需要注意的是:可以将右值引用变量用于初始化左值引用变量,但不可将左值引用变量用于初始化右值引用变量,因为右值引用变量自身属于左值。

初始化时可接受的形式int && 类型const int && 类型
int 变量不可以不可以
const int 变量不可以不可以
int & 变量不可以不可以
const int & 变量不可以不可以
int && 变量不可以不可以
const int && 变量不可以不可以
形如 100 的 int 字面常量可以可以
形如 1+50*2 的 int 多项表达式可以可以
返回类型为 int 的函数返回值可以可以
形如 100.0 可转换为 int 的字面常量可以可以
形如 1.0+50.0*2.0 可转换为 int 的多项表达式可以可以

扩展const常量与宏定义的常量的区别:

这个区别用从几个角度来说:

 1.const 定义的常数是变量 也带类型, #define 定义的只是个常数 不带类型。

2. define是在编译的预处理阶段起作用,而const是在 编译、运行的时候起作用。

3.define只是简单的字符串替换,没有类型检查。而const有对应的数据类型,是要进行判断的,可以避免一些低级的错误。 
由于define只是简单的字符串替换会导致边界效应,具体举例可以参考下面代码:

#define N 2+3 //我们预想的N值是5,我们这样使用N
double a = N/2;  //我们预想的a的值是2.5,可实际上a的值是3.5

4.占用的空间不同

#define PI 3.14     //预处理后 占用代码段空间
const float PI=3.14;    //本质上还是一个 float,占用数据段空间

5. const常量可以进行调试的,define是不能进行调试的,因为在预编译阶段就已经替换掉了

到此这篇关于C++ 右值引用与 const 关键字的文章就介绍到这了,更多相关C++ 右值引用const 关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++知识点之成员函数中const的用法

    C++知识点之成员函数中const的用法

    这篇文章主要介绍了C++知识点之成员函数中const的用法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C语言一看就懂的选择与循环语句及函数介绍

    C语言一看就懂的选择与循环语句及函数介绍

    函数是一个功能模块,它把实现某个功能的代码块包含起来,并起一个函数名,供别人调用,如printf函数,如system函数。是程序运行当中包装起来的一个步骤;选择与循环是编程中最常用的结构,本篇文章用最简单的文字带你了解它们
    2022-04-04
  • C语言字符串函数介绍与模拟实现详解

    C语言字符串函数介绍与模拟实现详解

    字符串函数(String processing function)也叫字符串处理函数,指的是编程语言中用来进行字符串处理的函数,如C,pascal,Visual以及LotusScript中进行字符串拷贝,计算长度,字符查找等的函数
    2022-02-02
  • C语言SQLite3事务和锁的操作实例

    C语言SQLite3事务和锁的操作实例

    这篇文章主要介绍了C语言SQLite3事务和锁的操作,结合完整实例形式分析了C语言针对SQLite3数据库的事务与锁相关操作技巧,需要的朋友可以参考下
    2017-07-07
  • QT实现提示右下角冒泡效果

    QT实现提示右下角冒泡效果

    这篇文章主要为大家详细介绍了QT实现提示右下角冒泡效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • Qt实现手动切换多种布局的完美方案

    Qt实现手动切换多种布局的完美方案

    通过点击程序界面上不同的布局按钮,使主工作区呈现出不同的页面布局,多个布局之间可以通过点击不同布局按钮切换,支持的最多的窗口为9个,不同布局下窗口数随之变化,这篇文章主要介绍了Qt实现手动切换多种布局的完美方案,需要的朋友可以参考下
    2024-07-07
  • OpenCV实现图像膨胀

    OpenCV实现图像膨胀

    这篇文章主要为大家详细介绍了OpenCV实现图像膨胀,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C++面试题之进制转换的实例

    C++面试题之进制转换的实例

    这篇文章主要介绍了C++面试题之进制转换的实例的相关资料,希望通过本文能帮助到大家,让大家理解掌握这样的知识,需要的朋友可以参考下
    2017-10-10
  • C语言实现循环单链表的示例代码

    C语言实现循环单链表的示例代码

    这篇文章主要给大家详细介绍了C语言如何实现循环单链表,文章通过代码示例讲解的非常详细,对我们的学习或工作有一定的参考价值,感兴趣的小伙伴跟着小编一起来看看吧
    2023-08-08
  • C++实现简单计算器

    C++实现简单计算器

    这篇文章主要为大家详细介绍了C++实现简单计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05

最新评论