《我的第一本c++书》学习笔记:c++之右值引用

本文深入探讨了C++中右值引用的概念及其在移动构造函数中的应用,详细解释了如何解决资源管理问题,包括实现move语义和完美转发。并通过代码示例展示了如何在实际开发中运用这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,在c++语言中,有一些数值,他们只能放在等号右边,只能用于对左值赋值,这样的数值称之为右值;右值通常是一些数值变量、临时变量和无名变量等。

而对于右值引用,在c++语言中,通过运算符“&&”来声明一个右值引用,对于之前的左值引用(即我们常说的引用),通过运算符“&”来声明引用。

这相关知识又与拷贝构造函数有关。

右值引用至少解决了这两个问题:
                                                          实现move语义
                                                          完美转发


可以用这样判断左右值:

左值是一个指向某内存空间的表达式,并且我们可以用&操作符获得该内存空间的地址。右值就是非左值的表达式。

// 1.cpp : 定义控制台应用程序的入口点。
//



#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <utility>



using namespace std;

class MemoryBlock
{
public:
	//构造函数,申请内存资源
	MemoryBlock( size_t length )
		: _length( length ) , _data( new int[length] )
	{
		cout<<"创建对象,长度 = "<<_length<<" , 申请资源"<<endl;
	}
	
	//析构函数,释放内存资源
	~MemoryBlock()
	{
		cout<< " 销毁对象,长度 = "<<_length<<",";
		if (  _data != NULL )
		{
			cout<<"释放资源";
			delete[] _data;
		}
		cout<<endl;
	}

	//拷贝构造函数
	MemoryBlock( const MemoryBlock& other )
		: _length(other._length) , _data(new int[other._length])
	{
		cout<<"复制构造函数,长度 = "<<other._length<<", 申请资源并复制资源到目标资源"<<endl;

		//复制源对象的内存资源到目标对象的内存资源
		copy( other._data, other._data + _length , _data );
		

	}

	MemoryBlock& operator = ( const MemoryBlock& other)
	{
		if ( this != &other )
		{
			cout<< "赋值操作符。长度 = "<<other._length
				<<",释放已有资源。 重新申请资源并复制资源到目标资源"<<endl;

			delete[] _data;

			_length = other._length;

			_data = new int[_length];
			//复制源对象的内存资源到目标对象的内存资源
			copy( other._data, other._data + _length, _data );

			return *this;
		}
	}

	size_t Length() const
	{
		return _length;
	}


private:
	size_t _length;            //内存资源长度
	int*   _data;             //对象的内存资源
};


int _tmain(int argc, _TCHAR* argv[])
{

	MemoryBlock a(3);
	MemoryBlock b(6);

	swap( a, b );
	

	return 0;
}

在编译时会出错:

c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(2176): error C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'。

则在stdafx.h头文件内定义了#define _SCL_SECURE_NO_WARNINGS,则编译通过。



下面为右值引用:

// 3.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>


using namespace std;


class MemoryBlock
{
public:
	MemoryBlock( size_t length )
		: _length( length ) , _data( new int[length] )
	{
		cout<<"创建对象,长度= "<<_length <<", 申请资源"<<endl;
	}
	~MemoryBlock()
	{
		cout<<"销毁对象,长度="<<_length<<", ";
		if ( NULL != _data )
		{
			cout<<"释放资源";
			delete[] _data;
		}
		cout<<endl;
	}
	//移动构造函数
	MemoryBlock(MemoryBlock&& other)
		: _length(0), _data(NULL)
	{
		cout<<"右值引用构造函数,长度= "<<other._length<<",将资源指向已有资源"<<endl;

		_length = other._length;
		_data   = other._data;

		other._length = 0;
		other._data   =NULL;
	}
	//移动赋值操作符“=”
	MemoryBlock& operator = (MemoryBlock&& other)
	{
		if (this != &other)
		{
			cout<<"右值引用赋值操作符,长度= "<<other._length<<endl;
			if ( NULL != _data )
			{
				cout<<",释放已有资源, "<<endl;
				delete[] _data;
			}
			_length = other._length;
			_data   = other._data;

			other._length = 0;
			other._data   =NULL;
		}
		return *this;
	}
	size_t Length() const
	{
		return _length;
	}

private:
	size_t _length;
	int*   _data;
};

int _tmain(int argc, _TCHAR* argv[])
{
	MemoryBlock a(3);
	MemoryBlock b(6);

	swap( a, b );

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值