- 这两个特性是c++11里比较有性能提升意义的。个人认为这两个特性也体现了c++对性能提升的极限追求。
- 通过改写经典c++面试题mystring来体会
- move不能减少临时变量的产生,但是可以减少内存的维护量
- 代码
-
//右值引用/*左值对象:持久存在的对象,具有名字,可以对其去地址右值对象:临时对象,表达式结束后它就没了,不能对它取地址,它也没有名字~右值引用类型:引用右值的类型,用&&来表示*//************************************************************************//*使用右值引用改进MyString类,添加移动构造函数 *//************************************************************************/#include<iostream>#include<vector>usingnamespace std;classMyString{public://普通构造函数MyString(){cout <<" default construct ";mLength =0;mData = NULL;}//带参数的普通构造函数MyString(constchar* str){cout <<" arg construct ";mLength = strlen(str);mData =newchar[mLength+1];memcpy(mData, str, mLength);mData[mLength]=' ';}//拷贝构造函数MyString(constMyString& str){cout <<" copy construct ";//深拷贝mLength = str.mLength;mData =newchar[mLength +1];memcpy(mData,str.mData,mLength);mData[mLength]=' ';}//移动构造函数MyString(MyString&& str){cout <<" move construct ";mLength = str.mLength;mData = str.mData;//str.mLength =0;str.mData = NULL;//这个是必须的,否则临时对象和此对象指向同一个资源,临时对象析构时会释放资源导致错误}//赋值函数MyString&operator=(constMyString& str){cout <<" operator = ";if(this!=&str){if(mData){delete[] mData;}mLength = str.mLength;mData =newchar[mLength +1];memcpy(mData, str.mData, mLength);mData[mLength]=' ';}return*this;}//右值赋值函数MyString&operator=(MyString&& str){cout <<" right ref operator = ";if(this!=&str){if(mData){delete[] mData;}mLength = str.mLength;mData = str.mData;str.mLength =0;str.mData = NULL;}return*this;}//析构函数~MyString(){cout <<" destruct ";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了。//移动语义的使用场合/************************************************************************//* 目的,通过右值和资源移动来实现临时对象资源的所有权转移,减少内存操作(申请拷贝释放),对含有堆资源的对象才比较有意义,而且必须实现相应的移动构造函数 *//************************************************************************/}