C++右值引用 移动语义

C++右值引用 移动语义,第1张

意义

避免拷贝

左值右值

C++ 左值、右值

左值引用
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 
#include 

#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();
}

输出

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1499309.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-25
下一篇 2022-06-25

随机推荐

发表评论

登录后才能评论

评论列表(0条)

保存