返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >一文带你了解C++中的右值引用与移动语义
  • 370
分享到

一文带你了解C++中的右值引用与移动语义

C++右值引用移动语义C++右值引用C++移动语义 2023-05-13 20:05:38 370人浏览 泡泡鱼
摘要

目录意义左值右值值类别左值纯右值将亡值左值引用右值引用std::move()移动构造&移动赋值运算符重载测试&验证意义 充分利用临时对象,避免拷贝。 左值右值 值类别

意义

充分利用临时对象,避免拷贝。

左值右值

值类别

c++11之后,C++根据

  • 被标识:可通过不同标识符指代同一实体。(对象/内存)
  • 可移动:可作为移动语义函数的参数,例如移动构造,移动赋值。

将值分为以下类别:

泛左值:被标识

  • 左值:被标识且不可移动
  • 将亡值:被标识可移动

右值:可移动

  • 将亡值:被标识可移动
  • 纯右值:不被标识且可移动

左值

int a = 1;

a是一个左值,左值是关联了名称的内存位置。

纯右值

int a = 1;

1是一个纯右值,纯右值是指不被标识且可移动的值,例如字面量。

将亡值

using std::string;
string get()
{
	string ret = "abc";
	return ret;
}

string str = get();

get() 函数调用会产生一个临时变量赋给str,这个临时变量是将亡值,此时的赋值是移动语义(c++11之前是复制语义)。

左值引用

int a = 1;
int& a_lref = a;

a_lref是左值引用

右值引用

int&& rref = 1;

rref是右值引用(rref是类型为右值引用的左值)

std::move()

void foo(int&& rref)
{
}

int a = 1;
foo(std::move(a));

std::move本质是类型转换,即把左值转换成右值

注意:被转换的对象不应再被使用,否则结果难以预计(通常内存会被转移)

移动构造&移动赋值运算符重载

class Foo
{

public:
	Foo()
	{
		m_data = malloc(32);
	}
	
	Foo(const Foo& rhs)
	{
		if(m_data == nullptr)
		{
			m_data = malloc(32);
		}
		memcopy(m_data,rhs.m_data,32);
	}
	
	Foo& operator = (const Foo& rhs)
	{
		if(m_data == nullptr)
		{
			m_data = malloc(32);
		}
		memcopy(m_data,rhs.m_data,32);
		return *this;
	}
	
	Foo(Foo&& rhs) noexcept
	{
		m_data = rhs.m_data;
		rhs.m_data = nullptr;
	}
	
	Foo& operator = (Foo&& rhs) noexcept
	{
		m_data = rhs.m_data;
		rhs.m_data = nullptr;
		return *this;
	}
private:
	void* m_data
}

移动构造的本质就是内存资源所有权的转移

测试&验证

#include <iOStream>
#include <cstdlib>

#define LOG(Args) std::cout << "==== " << Args << " ====" << std::endl

namespace My
{
	class Vector
	{
	public:
		Vector() noexcept
		{
			LOG("Ctor");
			m_data = new int[] {0, 0, 0, };
		}

		~Vector()
		{
			LOG("Dector");
			m_data = new int[] {0, 0, 0, };
		}

		Vector(const Vector& rhs)
		{
			LOG("Copy");
			if (m_data == nullptr)
			{
				m_data = new int[3];
			}
			memcpy(m_data, rhs.m_data, 3 * sizeof(int));

		}

		Vector& operator = (const Vector& rhs) 
		{
			LOG("Copy Operator = ");
			if (m_data == nullptr)
			{
				m_data = new int[3];
			}
			memcpy(m_data, rhs.m_data, 3 * sizeof(int));
			return *this;
		};

		Vector& operator = (Vector&& rhs) noexcept
		{
			LOG("Move Operator = ");
			m_data = rhs.m_data;
			rhs.m_data = nullptr;
			return *this;
		};

		Vector(Vector&& rhs) noexcept
		{
			LOG("Move");
			m_data = rhs.m_data;
			rhs.m_data = nullptr;
		}

		void print()
		{
			std::cout << "X = " << m_data[0] <<
				" , " << "Y = " << m_data[1] <<
				" , " << "Z = " << m_data[2] << std::endl;
		}

		void set(int x,int y,int z)
		{
			m_data[0] = x;
			m_data[1] = y;
			m_data[2] = z;
		}

	private:
		int* m_data;
	};
}

My::Vector Get()
{
	My::Vector vec;
	vec.set(4, 5, 6);
	return vec;
}

void main()
{
	My::Vector vec1;
	My::Vector vec2;

	LOG("vec1");
	vec1.print();

	vec1.set(0, 1, 2);
	LOG("vec1");
	vec1.print();

	vec1 = vec2;
	LOG("vec1");
	vec1.print();

	vec1 = std::move(vec2);
	LOG("vec1");
	vec1.print();

	My::Vector* vp1 = new My::Vector();
	LOG("vp1");
	vp1->print();

	My::Vector* vp2 = new My::Vector(*vp1);
	LOG("vp2");
	vp2->print();

	My::Vector* vp3 = new My::Vector(std::move(*vp1));
	LOG("vp3");
	vp3->print();

	My::Vector* vp4 = new My::Vector(Get());
	LOG("vp4");
	vp4->print();
}

输出

到此这篇关于一文带你了解C++中的右值引用与移动语义 的文章就介绍到这了,更多相关C++右值引用 移动语义 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 一文带你了解C++中的右值引用与移动语义

本文链接: https://lsjlt.com/news/202723.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 一文带你了解C++中的右值引用与移动语义
    目录意义左值右值值类别左值纯右值将亡值左值引用右值引用std::move()移动构造&移动赋值运算符重载测试&验证意义 充分利用临时对象,避免拷贝。 左值右值 值类别...
    99+
    2023-05-13
    C++右值引用 移动语义 C++右值引用 C++ 移动语义
  • C++左值与右值,右值引用,移动语义与完美转发详解
    目录C++——左值与右值、右值引用、移动语义与完美转发一、左值和右值的定义二、如何判断一个表达式是左值还是右值(大多数场景)三、C++右值引用四、std::m...
    99+
    2024-04-02
  • C++中右值引用与移动语义的方法是什么
    今天小编给大家分享一下C++中右值引用与移动语义的方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。意义充分利用临时对...
    99+
    2023-07-05
  • C++11右值引用和移动语义的实例解析
    目录基本概念左值 vs 右值左值引用 vs 右值引用右值引用使用场景和意义左值引用的使用场景左值引用的短板右值引用和移动语义右值引用引用左值右值引用的其他使用场景完美转发万能引用完美...
    99+
    2024-04-02
  • C++右值引用,移动语义与完美转发得方法
    本篇内容主要讲解“C++右值引用,移动语义与完美转发得方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++右值引用,移动语义与完美转发得方法”吧!C++&mdash;&mda...
    99+
    2023-06-29
  • C++11学习之右值引用和移动语义详解
    目录左值引用与右值引用1、左值与右值2、纯右值、将亡值3、左值引用与右值引用4、右值引用和 std::move 使用场景引用限定符const 和引用限定符移动语义—std...
    99+
    2023-02-23
    C++11右值引用 移动语义 C++11右值引用 C++11 移动语义
  • C++11右值引用和移动语义的方法是什么
    本文小编为大家详细介绍“C++11右值引用和移动语义的方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++11右值引用和移动语义的方法是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。左值引用与右值...
    99+
    2023-07-05
  • 一问了解C++的移动语义
    目录什么是移动语义?移动语义的好处通过右值使用移动语义移动语义的实例结论在 C++11 中,移动语义是一个重要的新特性,它可以使程序在内存管理方面更加高效,同时也提高了程序的性能。但...
    99+
    2023-05-15
    C++ 移动语义
  • C++右值引用与移动构造函数基础与应用详解
    目录1.右值引用1.1左值右值的纯右值将亡值右值1.2右值引用和左值引用2.移动构造函数2.1完美的移动转发1.右值引用 右值引用是 C++11 引入的与 Lambda 表达式齐名的...
    99+
    2023-02-13
    C++右值引用 C++移动构造函数
  • 带你一文了解C#中的Expression
    目录前言Expression与Expression Tree参考源码总结前言 我们书接上文,我们在了解LINQ下面有说到在本地查询IEnumerbale主要是用委托来作为传参,而解析...
    99+
    2024-04-02
  • 带你一文了解C#中的LINQ
    目录前言LINQ的根基IEnumerable和IEnumeratorLINQ的基本用法扩展方法在LINQ的应用:LINQ的流式语法LINQ的查询表达式:LINQ的查询语法LINQ的延...
    99+
    2024-04-02
  • 一文带你了解C++中deque的使用
    目录1)deque的定义及基本用法2)deque的迭代器3)deque的性能4)deque的应用:滑动窗口问题1)deque的定义及基本用法 要使用deque,我们需要包含头文件,定...
    99+
    2023-05-18
    C++ deque使用 C++ deque原理 C++ deque
  • 一文带你了解C++中queue的使用
    目录一、queue的定义二、queue的使用三、queue的原理四、queue的示例一、queue的定义 queue是一个类模板。它包含在头文件中。其定义形式如下: template...
    99+
    2023-05-18
    C++ queue使用 C++ queue原理 C++ queue
  • 一文带你了解C#中的协变与逆变
    目录协变协变接口的实现逆变里氏替换原则协变 协变概念令人费解,多半是取名或者翻译的锅,其实是很容易理解的。 比如大街上有一只狗,我说大家快看,这有一只动物!这个非常自然,虽然动物并不...
    99+
    2023-02-26
    C# 协变 逆变 C# 协变 C# 逆变
  • 一文带你了解Java中数值与集合的区别
    一文带你了解Java中数值与集合的区别?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。数组array和集合的区别:(1) 数值是大小固定的,同一数组只能存放一样的数据。(2) j...
    99+
    2023-05-31
    java 集合 数组
  • 一文带你深入了解Python中的二次移动平均法
    目录二次移动平均法逻辑Python代码实现第二种实现二次移动平均法的方式第三种卷积实现二次移动平均法二次移动平均法的应用场景二次移动平均法逻辑 二次移动平均法是一种重要的数学工具,用...
    99+
    2023-02-01
    Python二次移动平均法 Python 平均法
  • 聊聊C++中右值引用和移动构造函数的使用
    目录一: 背景二: 右值引用1. 它到底解决了什么问题2. 右值引用是个什么样子三: 右值引用如何减少对象的创建1. 简要思路2. 一个简单的例子3. 性能优化方案四: 总结一: 背...
    99+
    2024-04-02
  • C++右值引用与移动构造函数应用的方法是什么
    这篇文章主要讲解了“C++右值引用与移动构造函数应用的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++右值引用与移动构造函数应用的方法是什么”吧!1.右值引用右值引用是 C++...
    99+
    2023-07-05
  • 一篇文章带你了解C语言的文件操作
    目录为什么使用文件什么是文件程序文件数据文件文件名文件的打开和关闭文件指针fopen和fclose函数文件的顺序读写总结为什么使用文件 我们在想既然是通讯录就应该把信息记录下来,只有...
    99+
    2024-04-02
  • 一篇文章带你了解C++中的异常
    目录异常抛出异常基本操作自定义的异常类栈解旋异常接口声明异常变量的生命周期异常的多态c++的标准异常库编写自己的异常类总结异常 在c语言中,对错误的处理总是两种方法: 1,使用整型的...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作