右值引用-2移动语义,完美转发

移动语义的例子

#include<iostream>
#include<vector>
using namespace std;

#define pfunc  \
cout << __FUNCTION__<<":"<<__LINE__ << endl;

class MyString
{
public:
   MyString() :m_data(nullptr), m_len(0)
   {
   	pfunc;
   }
   MyString(const char* pstr)
   {
   	pfunc;
   	m_len = strlen(pstr);
   	copy_data(pstr);
   }
   //拷贝构造
   MyString(const MyString& other)
   {
   	pfunc;
   	if (other.m_data)
   	{
   		m_len = other.m_len;
   		release_data();
   		copy_data(other.m_data);
   	}
   }
   //赋值构造
   MyString& operator=(const MyString& other)
   {
   	pfunc;
   	if (this != &other)
   	{
   		m_len = other.m_len;
   		release_data();
   		copy_data(other.m_data);
   	}
   	return *this;
   }

   // 移动拷贝构造, 偷other的资源
   MyString(MyString&& other)
   {
   	pfunc;
   	m_len = other.m_len;
   	m_data = other.m_data;
   	other.m_data = nullptr;
   }
   // 移动赋值构造
   MyString operator+(MyString& other)
   {
   	pfunc;
   	MyString temp;
   	temp.m_len = other.m_len + this->m_len;
   	temp.m_data = new char[temp.m_len + 1];

   	memcpy(temp.m_data, this->m_data, this->m_len);
   	memcpy(temp.m_data+this->m_len, other.m_data, other.m_len);
   	temp.m_data[temp.m_len] = 0;

   	return temp;
   }

   ~MyString()
   {
   	release_data();
   }
private:
   void copy_data(const char* pdata)
   {
   	if (pdata)
   	{
   		m_data = new char[m_len + 1];
   		memcpy(m_data, pdata, m_len);
   		m_data[m_len] = 0;
   	}
   }
   void release_data()
   {
   	if (m_data)
   	{
   		delete m_data;
   		m_data = nullptr;
   	}
   }
private:
   char* m_data = nullptr;
   size_t m_len = 0;
};

MyString test()
{
   MyString t("test");
   return t;
}

int main()
{

   MyString s1 = "Hello World";
   MyString s2(s1);
   MyString s3 = move(s1);// call move constructor
   MyString s11 = " Good Morning";
   MyString s4 = s2 + s11;// call move constructor
   MyString s5(std::forward<MyString>(s3));// call move constructor
   return 0;
}

2 move函数
把左值当成右值使用,比如swap函数

template<class _Ty,
	class> inline
	void swap(_Ty& _Left, _Ty& _Right)
		_NOEXCEPT_COND(is_nothrow_move_constructible_v<_Ty>
			&& is_nothrow_move_assignable_v<_Ty>)
	{	// exchange values stored at _Left and _Right
	_Ty _Tmp = _STD move(_Left);
	_Left = _STD move(_Right);
	_Right = _STD move(_Tmp);
	}
  1. forward函数
    forward函数如上面的例子,也可以把左值当成右值使用。
    但它不仅仅是这样。通过它可以实现完美转发,完美转发就是一个函数将参数继续转交给另一个函数进行处理,原参数可能是右值,可能是左值,如果还能继续保持参数的原有特征,就是完美。
    其实,forward可以替代move,不过最佳实践告诉我们,右值引用使用move,万能引用使用forward
template<typename T>
void print(T& t) {
	cout << "left value" << endl;
}
template<typename T>
void print(T&& t) {
	cout << "right value" << endl;
}

template<typename T>
void MyForward(T && v) {

	print(std::forward<T>(v));
}
int main() {
	int x = 404;
	MyForward(11);
	MyForward(x);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章