右值引用-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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章