C++中右值引用与移动语义的方法是什么

发布时间:2023-03-31 11:16:40 作者:iii
来源:亿速云 阅读:169

今天小编给大家分享一下C++中右值引用与移动语义的方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

意义

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

左值右值

值类别

在 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++中右值引用与移动语义的方法是什么”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注亿速云行业资讯频道。

推荐阅读:
  1. Linux中安装google的libphonenumber c++库方法是什么
  2. C/C++函数库调用与系统调用的区别有哪些

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++

上一篇:springboot访问404问题如何解决

下一篇:Vue响应式原理与虚拟DOM如何实现

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》