标签:
//右值引用
/*
左值对象:持久存在的对象,具有名字,可以对其去地址
右值对象:临时对象,表达式结束后它就没了,不能对它取地址,它也没有名字~
右值引用类型:引用右值的类型,用&&来表示
*/
/************************************************************************/
/*使用右值引用改进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