- 這兩個特性是c++11里比較有性能提升意義的。個人認為這兩個特性也體現了c++對性能提升的極限追求。
- 通過改寫經典c++面試題mystring來體會
- move不能減少臨時變量的產生,但是可以減少內存的維護量
- 代碼
-
//右值引用/*左值對象:持久存在的對象,具有名字,可以對其去地址右值對象:臨時對象,表達式結束后它就沒了,不能對它取地址,它也沒有名字~右值引用類型:引用右值的類型,用&&來表示*//************************************************************************//*使用右值引用改進MyString類,添加移動構造函數 *//************************************************************************/#include<iostream>#include<vector>usingnamespace std;classMyString{public://普通構造函數MyString(){cout <<"\n default construct\n";mLength =0;mData = NULL;}//帶參數的普通構造函數MyString(constchar* str){cout <<"\n arg construct\n";mLength = strlen(str);mData =newchar[mLength+1];memcpy(mData, str, mLength);mData[mLength]='\0';}//拷貝構造函數MyString(constMyString& str){cout <<"\n copy construct\n";//深拷貝mLength = str.mLength;mData =newchar[mLength +1];memcpy(mData,str.mData,mLength);mData[mLength]='\0';}//移動構造函數MyString(MyString&& str){cout <<"\n move construct\n";mLength = str.mLength;mData = str.mData;//str.mLength =0;str.mData = NULL;//這個是必須的,否則臨時對象和此對象指向同一個資源,臨時對象析構時會釋放資源導致錯誤}//賦值函數MyString&operator=(constMyString& str){cout <<"\n operator = \n";if(this!=&str){if(mData){delete[] mData;}mLength = str.mLength;mData =newchar[mLength +1];memcpy(mData, str.mData, mLength);mData[mLength]='\0';}return*this;}//右值賦值函數MyString&operator=(MyString&& str){cout <<"\n right ref operator = \n";if(this!=&str){if(mData){delete[] mData;}mLength = str.mLength;mData = str.mData;str.mLength =0;str.mData = NULL;}return*this;}//析構函數~MyString(){cout <<"\n destruct \n";if(mData){delete[] mData;mData = NULL;}}public:size_t mLength;char* mData;};MyStringGetString(){MyString str("test str");return str;}int main(){int i =0;//i是左值,0是右值MyString a;MyString b("b");//這兩個寫法,對於編譯器來說是一樣的MyString c(b);MyString d = c;//這個只調用拷貝構造函數,不會調用賦值函數;分兩行寫就會調用賦值,為什么會這樣。。。MyString e =GetString();MyString f(GetString());//調用移動構造函數MyString h;h =MyString();//調用右值賦值函數MyString g;g = e;//調用賦值函數MyString m;m =GetString();vector<MyString> v;MyString str("123");v.push_back(str);//會創建臨時變量,調用拷貝構造函數v.push_back(std::move(str));//調用移動構造函數,std::move將左值引用轉化為右值引用,//push_back在接受右值引用后調用類的移動構造函數將資源移動到//容器中,而右值引用對應的對象具體處理要參考具體移動構造函數的實現。我這里是將資源設null了。//移動語義的使用場合/************************************************************************//* 目的,通過右值和資源移動來實現臨時對象資源的所有權轉移,減少內存操作(申請拷貝釋放),對含有堆資源的對象才比較有意義,而且必須實現相應的移動構造函數 *//************************************************************************/}
