//右值引用/*左值对象:持久存在的对象,具有名字,可以对其去地址右值对象:临时对象,表达式结束后它就没了,不能对它取地址,它也没有名字~右值引用类型:引用右值的类型,用&&来表示*//************************************************************************//*使用右值引用改进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了。//移动语义的使用场合/************************************************************************//* 目的,通过右值和资源移动来实现临时对象资源的所有权转移,减少内存操作(申请拷贝释放),对含有堆资源的对象才比较有意义,而且必须实现相应的移动构造函数 *//************************************************************************/}原文:http://www.cnblogs.com/dongdongweiwu/p/4743661.html