c++11 移動語義
阿新 • • 發佈:2017-11-05
應用程序 color 值引用 移動語義 delete system fine blog 相對
c++11 移動語義
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <vector> #include <map> // C++中還有一個被廣泛認同的說法,那就是可以取地址的、有名字的就是左值,反之,不能取地址的、沒有名字的就是右值。 // 相對於左值,右值表示字面常量、表達式、函數的非引用返回值等。 /* 右值引用是用來支持轉移語義的。 轉移語義可以將資源 ( 堆,系統對象等 ) 從一個對象轉移到另一個對象,這樣能夠減少不必要的臨時對象的創建、拷貝以及銷毀,能夠大幅度提高 C++ 應用程序的性能。臨時對象的維護 ( 創建和銷毀 ) 對性能有嚴重影響。 轉移語義是和拷貝語義相對的,可以類比文件的剪切與拷貝,當我們將文件從一個目錄拷貝到另一個目錄時,速度比剪切慢很多。 通過轉移語義,臨時對象中的資源能夠轉移其它的對象裏。*/ /* 移動語義定義: 在現有的 C++ 機制中,我們可以定義拷貝構造函數和賦值函數。 要實現轉移語義,需要定義轉移構造函數,還可以定義轉移賦值操作符。 對於右值的拷貝和賦值會調用轉移構造函數和轉移賦值操作符。 如果轉移構造函數和轉移拷貝操作符沒有定義,那麽就遵循現有的機制,拷貝構造函數和賦值操作符會被調用。 普通的函數和操作符也可以利用右值引用操作符實現轉移語義。 */ class MyString { public: MyString(const char *tmp = "abc") {//普通構造函數 len = strlen(tmp); //長度 str = newchar[len+1]; //堆區申請空間 strcpy(str, tmp); //拷貝內容 cout << "普通構造函數 str = " << str << endl; } MyString(const MyString &tmp) {//拷貝構造函數 len = tmp.len; str = new char[len + 1]; strcpy(str, tmp.str); cout << "拷貝構造函數 tmp.str =" << tmp.str << endl; } //移動構造函數 //參數是非const的右值引用 MyString(MyString && t) { str = t.str; //拷貝地址,沒有重新申請內存 len = t.len; //原來指針置空 t.str = NULL; cout << "移動構造函數" << endl; } MyString &operator= (const MyString &tmp) {//賦值運算符重載函數 if(&tmp == this) { return *this; } //先釋放原來的內存 len = 0; delete []str; //重新申請內容 len = tmp.len; str = new char[len + 1]; strcpy(str, tmp.str); cout << "賦值運算符重載函數 tmp.str = " << tmp.str << endl; return *this; } //移動賦值函數 //參數為非const的右值引用 MyString &operator=(MyString &&tmp) { if(&tmp == this) { return *this; } //先釋放原來的內存 len = 0; delete []str; //無需重新申請堆區空間 len = tmp.len; str = tmp.str; //地址賦值 tmp.str = NULL; cout << "移動賦值函數\n"; return *this; } ~MyString() {//析構函數 cout << "析構函數: "; if(str != NULL) { cout << "已操作delete, str = " << str; delete []str; str = NULL; len = 0; } cout << endl; } private: char *str = NULL; int len = 0; }; MyString func() //返回普通對象,不是引用 { MyString obj("mike"); return obj; } void mytest() { MyString &&tmp1 = func(); //右值引用接收 MyString tmp2("abc"); //實例化一個對象 tmp2 = func(); return; } int main() { mytest(); system("pause"); return 0; }
c++11 移動語義