左值與右值的定義ios
C++( 包括 C) 中全部的表達式和變量要麼是左值,要麼是右值。通俗的左值的定義就是非臨時對象,那些能夠在多條語句中使用的對象。windows
全部的變量都知足這個定義,在多條代碼中均可以使用,都是左值。右值是指臨時的對象,它們只在當前的語句中有效(好比當即數,未命名對象)安全
//注意 考慮到安全因素,具名變量即便被聲明爲右值類型也不會被看成右值 而要用std::move函數(如下說明)函數
右值引用 實現了 語意轉移 和 完美轉發this
語意轉移 std::movespa
用途 沒有了無心義的拷貝工做,效率大大提高code
編譯器只對右值引用才能調用轉移構造函數和轉移賦值函數,而全部命名對象都只能是左值引用,若是已知一個命名對象再也不被使用而想對它調用轉移構造函數和轉移賦值函數,也就是把一個左值引用當作右值引用來使用,怎麼作呢?標準庫提供了函數 std::move,這個函數以很是簡單的方式將左值引用轉換爲右值引用。對象
示例1 string str_1 = "123"; string s(std::move(str_1));/*str_1被轉移構造到了s*/ //string(&&) //string s2(str_1);/*拷貝構造函數*/ //string(string&) std::cout << s << endl;;/*123*/ cout << str_1 << endl;/*str_1已被轉移 因此爲空*/ 示例2 #include<iostream> #include "vector" #include "string" #include "functional" #include "windows.h" using namespace std; class _string { public: char*_data; void alloc() { _data = (char*)malloc(sizeof(char)* 100); } _string&operator=(const char*s) { cout << "call =const char*" << endl; strcpy(_data, s); return *this; } _string &operator=(const _string& s) { cout << "call = const string&" << endl; strcpy(_data, s.c_str()); return *this; } _string &operator=(_string&&s) { cout << "call =string&&" << endl; this->_data = s._data; s._data = 0; return *this; } _string(_string&&s) { cout << "call string string &&" << endl; this->_data = s._data; s._data = 0; } _string(_string&s) { alloc(); cout << "call string string &" << endl; strcpy(_data, s.c_str()); } _string(const char*s) { alloc(); cout << "call string const char*" << endl; strcpy(_data, s); } _string(const _string&s) { alloc(); cout << "call string const string &" << endl; strcpy(_data, s.c_str()); } _string() { alloc(); cout << "call string" << endl; strcpy(_data, "\0"); } ~_string() { if (_data) { cout << "call ~_stirng with free" << endl; free(_data); return; } cout << "call ~_stirng" << endl; } const char* c_str() const { return (const char*)_data; } }; _string func() { _string str = "65546465"; //return str; return std::move(str); } int main() { //{ _string&& s = (func()); //} system("pause"); return 0; }