型別 && 參照名 = 右值表示式;
例如:class A{}; A & rl = A(); //錯誤,無名臨時變數 A() 是右值,因此不能初始化左值參照 r1 A && r2 = A(); //正確,因 r2 是右值參照
#include <iostream> #include <string> #include <cstring> using namespace std; class String { public: char* str; String() : str(new char[1]) { str[0] = 0; } String(const char* s) { str = new char[strlen(s) + 1]; strcpy(str, s); } String(const String & s) {//複製建構函式 cout << "copy constructor called" << endl; str = new char[strlen(s.str) + 1]; strcpy(str, s.str); } String & operator = (const String & s) {//複製賦值號 cout << "copy operator = called" << endl; if (str != s.str) { delete[] str; str = new char[strlen(s.str) + 1]; strcpy(str, s.str); } return *this; } String(String && s) : str(s.str) { //移動建構函式 cout << "move constructor called" << endl; s.str = new char[1]; s.str[0] = 0; } String & operator = (String && s) { //移動賦值號 cout << "move operator = called" << endl; if (str != s.str) { str = s.str; s.str = new char[1]; s.str[0] = 0; } return *this; } ~String() { delete[] str; } }; template <class T> void MoveSwap(T & a, T & b) { T tmp(move(a)); //std::move(a) 為右值,這裡會呼叫移動建構函式 a = move(b); //move(b) 為右值,因此這裡會呼叫移動賦值號 b = move(tmp); //move(tmp) 為右值,因此這裡會呼叫移動賦值號 } int main() { String s; s = String("this"); //呼叫移動賦值號 cout << "* * * *" << endl; cout << s.str << endl; String s1 = "hello", s2 = "world"; MoveSwap(s1, s2); //呼叫一次移動建構函式和兩次移動賦值號 cout << s2.str << endl; return 0; }程式的輸出結果如下:
String("this")
是右值,因此在定義了移動賦值號的情況下,會導致移動賦值號被呼叫。移動賦值號使得 s 的內容和 String("this") 一致,然而卻不用執行深複製操作,因而效率比複製賦值號高。template <class T> void Swap(T & a, T & b) { T tmp(a); //呼叫複製建構函式 a=b; //呼叫複製賦值號 b=tmp; //呼叫複製賦值號 }Swap 函數執行期間會呼叫一次複製建構函式,兩次複製賦值號,即一共會進行三次深複製操作。而利用右值參照,使用 MoveSwap,則可以在無須進行深複製的情況下達到相同的目的,從而提高了程式的執行效率。