【深入理解C++】左值引用、常引用、右值引用、std::move()函数

news2025/7/28 18:33:27

文章目录

  • 1.左值引用
  • 2.常引用
    • 2.1 const引用可以指向临时数据
    • 2.2 const引用可以指向不同类型的数据
    • 2.3 const引用作为函数参数
  • 3.右值引用
  • 4.std::move()函数

1.左值引用

左值引用只能绑定到左值上,不能绑定到右值上。

左值引用不能绑定到临时变量上,因为临时变量被系统当作右值。

所有变量都是左值,因为它们是有地址的。

任何函数里边的形参都是左值。

#include <iostream>
using namespace std;

int main()
{
	int& ref1 = 20; // 错误,左值引用不能绑定到右值上

	int a = 10, b = 20;

	int& ref2 = a; // 正确,左值引用能绑定到左值上	

	int& ref3 = a + b; // 错误,左值引用不能绑定到右值上

	return 0;
}

返回左值引用的函数、赋值运算符、下标运算符、解引用运算符、前置递增运算符、前置递减运算符等,返回的都是左值,可以将左值引用绑定到这类表达式的结果上。

#include <iostream>
using namespace std;

int main()
{
	int i = 10;
	int& ref = ++i; // 左值引用可以绑定到左值上,ref就变成了i的别名
	i += 5;
	cout << i << endl; // 16
	cout << ref << endl; // 16

	return 0;
}

2.常引用

引用可以被 const 修饰,这样就无法通过引用修改数据了,称为常引用。const 必须写在 & 符号的左边,才能算是常引用。

引用 int &p 相当于 int* const p,常引用 const int &p 相当于 const int* const p

#include <iostream>
using namespace std;

int main() {

	int height = 20;
	int age = 10;

	// p1不能修改指向,但是可以利用p1间接修改所指向的变量
	int* const p1 = &age;
	//p1 = &height; // 报错
	*p1 = 30;
	cout << age << endl; // 30

	// ref1不能修改指向,但是可以通过ref1间接修改所指向的变量
	int & const ref1 = age;
	ref1 = 40;
	cout << age << endl; // 40

	// p2可以修改指向,但是不可以利用p2间接修改所指向的变量
	int const* p2 = &age;
	p2 = &height;
	//*p2 = 30; // 报错

	// ref2不能修改指向,也不可以通过ref2间接修改所指向的变量
	int const &ref2 = age; // 常引用
	//ref2 = 40; // 报错

	return 0;
}

2.1 const引用可以指向临时数据

举例1:const引用指向常量

#include <iostream>
using namespace std;

int main() {

	const int &ref = 30;

	return 0;
}

举例2:const引用指向表达式

#include <iostream>
using namespace std;

int main() {

	int a = 1;
	int b = 2;
	const int &ref = a + b;

	return 0;
}

举例3:const引用指向函数返回值

#include <iostream>
using namespace std;

int func() {
	return 8;
}

int main() {

	const int &ref = func();

	return 0;
}

2.2 const引用可以指向不同类型的数据

#include <iostream>
using namespace std;

int main() {
	int age = 10;

	const double &ref = age;

	return 0;
}

当常引用指向了不同类型的数据时,会产生临时变量,即引用指向的并不是初始化时的那个变量。

举例1:查看常引用指向相同类型数据的汇编代码

#include <iostream>
using namespace std;

int main() {

	int age = 10;
	const int &ref = age;
	age = 30;

	cout << age << endl; // 30
	cout << ref << endl; // 30

	return 0;
}

在这里插入图片描述

举例2:查看常引用指向不同类型数据的汇编代码

#include <iostream>
using namespace std;

int main() {

	int age = 10;
	const long &ref = age;
	age = 30;

	cout << age << endl; // 30
	cout << ref << endl; // 10

	return 0;
}

在这里插入图片描述

2.3 const引用作为函数参数

const引用作为函数参数时,可以接受const和非const实参。

非const引用作为函数参数时,只能接受非const实参。

const引用跟非const引用可以构成函数重载。

const引用作为函数参数时的上述规则也适用于const指针。

#include <iostream>
using namespace std;

int sum(int &v1, int &v2) {
	cout << "sum(int &v1, int &v2)" << endl;
	return v1 + v2;
}

int sum(const int &v1, const int &v2) {
	cout << "sum(const int &v1, const int &v2)" << endl;
	return v1 + v2;
}

int main() {

	// 非const实参
	int a = 10;
	int b = 20;
	sum(a, b);
	
	// const实参
	const int c = 10;
	const int d = 20;
	sum(c, d);
	
	sum(10, 20);

	return 0;
}

输出结果如下:

在这里插入图片描述

3.右值引用

右值引用只能绑定到右值上,不能绑定到左值上。右值引用通常绑定到一些即将销毁的或一些临时的对象上。

#include <iostream>
using namespace std;

int main()
{
	int&& ref1 = 10; // 正确,右值引用能绑定到右值上

	int a = 100, b = 200;

	int&& ref2 = a; // 错误,右值引用不能绑定到左值上

	int&& ref3 = a * b; // 正确,右值引用能绑定到右值上

	return 0;
}

返回非引用类型的函数、算术运算符、关系运算符、位运算符、后置递增运算符、后置递减运算符等,返回的都是右值,不能将左值引用绑定到这类表达式上,可以将常引用或右值引用绑定到这类表达式上。

#include <iostream>
using namespace std;

int main()
{
	int i = 10;
	int&& ref = i++; // 右值引用绑定到临时变量上,此后ref和i没有关系
	i += 5;
	cout << i << endl; // 16
	cout << ref << endl; // 10

	return 0;
}

4.std::move()函数

std::move() 的能力只有一个:把一个左值强制转换成一个右值。实际上这个函数根本就没有做移动的操作。

#include <iostream>
using namespace std;

int main()
{
	int i = 10;
	int&& ref = std::move(i); // 把一个左值强制转换成一个右值
	i = 20;
	cout << i << endl; // 20
	cout << ref << endl; // 20

	return 0;
}
#include <iostream>
using namespace std;

int main()
{
	int&& ref1 = 100;
	int&& ref2 = std::move(ref1); // 把一个左值强制转换成一个右值
	ref1 = 200;
	cout << ref1 << endl; // 200
	cout << ref2 << endl; // 200

	return 0;
}
#include <iostream>
using namespace std;

int main()
{
	string src = "I love China!";
	string dst = std::move(src); // string里的移动构造函数把src的内容转移到dst中去了,而不是std::move()转移的
	cout << "&src = " << &src << ", src = " << src << endl;
	cout << "&dst = " << &dst << ", dst = " << dst << endl;

	return 0;
}

输出结果如下:

在这里插入图片描述

#include <iostream>
using namespace std;

int main()
{
	string src = "I love China!";
	string&& ref = std::move(src); // 把一个左值强制转换成一个右值
	cout << "&src = " << &src << ", src = " << src << endl;
	cout << "&dst = " << &ref << ", dst = " << ref << endl;

	return 0;
}

输出结果如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/16359.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

是德N5290A矢量网络分析仪技术参数及操作步骤

网络分析仪能对被测量器件(主要分为有源元件和无源元件)的线性和非线性特性(幅频特性&#xff0c;相频特性&#xff0c;时频特性&#xff0c;功率频率特性等)进行表征。 那么大家真的了解网络分析仪吗?下面西安安泰测试以是德科技(安捷伦)E50系列矢量网络分析仪为例介绍仪器基…

基于PHP+MySQL汽车租赁管理系统的设计与实现

虽然汽车已经进入了家家户户,但是很多时候人们因为各种原因需要进行汽车的租赁,可能是到达的城市比较远,也可能是经济实力不允许,或者是对车辆的要求不高,暂时没必要买车等,这些特殊的原因导致了汽车租赁行业的兴起。越来越多的用车用户希望通过租赁来直接获取使用的使用权,这样…

四、C++ 类的继承

文章目录一、引言1.1 类成员的三种类型1.2 访问控制和继承二、类的继承2.1 格式2.2 继承类型三、多继承一、引言 1.1 类成员的三种类型 我们知道&#xff0c;在类中一共有三种类型&#xff0c;分别为public&#xff0c;private和protected&#xff0c;默认为private&#xff…

redhat6.5安装nvidia驱动

iso&#xff1a;redhat6.5 1、下载安装NVIDIA显卡驱动 1.1 打开终端 1.2 输入下方代码进行查看自己的显卡型号 lspci |grep -i nvidia 2、在官网下载对应的驱动&#xff1a; 官方驱动 | NVIDIA 3、禁用nouveau驱动 3.1 禁用默认的nouveau&#xff0c;据说这是NVIDIA显卡…

yolox原理

目录 1 Decoupled Head 1.1 YOLOX的解耦头结构思考 2 Data Augmentation 别人讲的好的文章&#xff0c;yolox作者写的 以下正文部分内容&#xff0c;参考该链接 如何评价旷视开源的YOLOX&#xff0c;效果超过YOLOv5? - 知乎感谢大家对旷视开源的 YOLOX 关注&#xff0c;本…

数字化外协生产综合管理系统,实现信息自动同步,数据自动统计分析!

随着市场经济的不断发展&#xff0c;制造生产行业竞争不断加剧&#xff0c;精细化、无纸化办公已成为生产企业生存和发展的基本条件。要想将企业内部管理做的更精更细&#xff0c;就必须借助于现代先进的企业管理手段和工具&#xff0c;如企业资源计划系统、生产管理系统等。 …

Linux安装Apache(解压版)

安装依赖 yum -y install gcc perl wget make pcre-devel openssl-devel expat-devel 安装目录 mkdir /opt/apache && cd /opt/apache 安装包下载 wget https://dlcdn.apache.org/apr/apr-1.7.0.tar.gz --no-check-certificate wget https://dlcdn.apache.org/apr/apr-…

谈谈数据分析晓知识

随着数字化转型普遍开展,数据分析飞速发展。无论您的组织属于哪个行业,数据分析都可能在制定战略中发挥着关键作用。许多公司现在都有数据分析师,他们对原始数据采用数据挖掘技术,从这个过程中获得的许多可行的洞察和见解。 同时,数据分析软件市场迅速攀升。根据IDC的数据…

【iOS-UIImagePickerController访问相机和相册】

文章目录记录UIImagePickerControllerUIImagePickerController的sourceType主要代码点击imageView事件跳转到相机和相册![请添加图片描述](https://img-blog.csdnimg.cn/0a5a307de371421eba7e3472075dcaeb.png)总结记录 在写知乎日报的时候用到过imageVIew点击事件&#xff0c…

函数式编程

Lambda表达式介绍 Lambda简介 Lambda 表达式是 JDK8 的一个新特性&#xff0c;可以取代大部分的匿名内部类&#xff0c;写出更优雅的 Java 代码&#xff0c;尤其在集合的遍历和其他集合操作中&#xff0c;可以极大地优化代码结构。 在Java语言中&#xff0c;可以为变量赋予一…

连续六个季度实现盈利改善,达达集团内外双重确定性凸显

当消费迈向复苏时&#xff0c;今年的社会消费品零售也在总额恢复增长的情况下&#xff0c;迎来结构性变化。 其中&#xff0c;一股消费力量的加速增长成为了重点——即时零售。今年7月&#xff0c;商务部在官网发布的《2022年上半年中国网络零售市场发展报告》&#xff0c;首次…

VOACAP 软件的下载与安装

VOACAP 简介 VOACAP(Voice of America Coverage Analysis Program&#xff0c;美国之音覆盖分析程序)软件是NTIA/ITS开发的高频规划软件包 ITS HF Propagation 中的一个电路计算模块&#xff0c;它是对原 ITS IONCAP 模块(高频传输系统应用预测模块之一)的改进&#xff0c;并根…

LogTAD:无监督跨系统日志异常域检测

摘要 日志异常检测&#xff0c;其对开发稳定、可持续的系统具有重要意义。但当系统刚上线时&#xff0c;收集足够的数据训练一个无监督模型是不现实的。为此本文提出了一个可转移的日志异常检测(LogTAD)框架&#xff0c;该框架利用对抗域适应技术使来自不同系统的日志数据具有…

小程序最新获取用户头像昵称

目录 一、前言 二、遇到的问题 三、效果页面 四、代码实现 记录&#xff1a; 一、前言 昨天打开编辑器后&#xff0c;发现小程序用户的头像与昵称都给变默认了&#xff0c;就去网上搜了一下&#xff1a; 小程序用户头像昵称获取规则调整公告 | 微信开放社区 我去&…

Spring6整合JUnit5

十七、Spring6整合JUnit5 17.1 Spring对JUnit4的支持 准备工作&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instanc…

[附源码]java毕业设计暖暖猫窝系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Linux之软连接和硬连接的用法和区别【详细!!!】

目录软连接创建一个软连接删除软连接硬链接创建硬链接删除硬链接硬链接和软连接之间的区别软连接 创建一个软连接 ln -s [源文件或目录] [软连接名称] 例子&#xff1a; 在/home目录下创建一个软连接linkToRoot 链接到/root目录 删除软连接 rm -f /linkToRoot例子&#x…

供应CAS:73342-16-2,N3-PEG-OH,Azide-PEG-Hydroxy,叠氮-聚乙二醇-羟基

一&#xff1a;产品描述 1、名称 英文&#xff1a;N3-PEG-OH&#xff0c;Azide-PEG-Hydroxy 中文&#xff1a;叠氮-聚乙二醇-羟基 2、CAS编号&#xff1a;73342-16-2 3、所属分类&#xff1a;Azide PEG Hydroxyl PEG 4、分子量&#xff1a;可定制&#xff0c;叠氮-PEG 34…

[附源码]java毕业设计某公司酬薪管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

无需重启应用,动态采集任意点位日志

作者&#xff1a; 屿山 现实系统往往有着较高的复杂度&#xff0c;我们借助 Trace、Log、Metric 三驾马车使我们的系统具备了一定的可观测性&#xff0c;但观测位置和信息往往是固定的&#xff0c;而我们所遇到的问题常常是意料之外的&#xff0c;这就导致我们能够定位问题的范…