右值引用(及其支持的Move语意和完美转发)是C++0x将要加入的最重大语言特性之一.从实践角度讲,它能够完美解决C++中长久以来为人所诟病的临时对象效率问题。从语言本身讲,它健全了C++中的引用类型在左值右值方面的缺陷。从库设计者的角度讲,它给库设计者又带来了一把利器。从库使用者的角度讲,不动一兵一卒便可以获得“免费的”效率提升…
右值引用
在C++03中,临时变量(右值,出现在等号右侧的变量。另一种解释是引用值,没有实际地址的值)和const & type没有实际的差别。而在C++0X标准中添加了一种新的引用类型。叫做右值引用。它的定义类似于typename &&。另外右值引用提供了一种转移语义。
C++代码块:
#include <stdio.h>
#include <tchar.h>
#include <vector>
#include <iostream>
using namespace std;
class ObjA
{
public:
ObjA():data(NULL)
{
cout<<_T("调用构造函数")<<endl;
}
ObjA(const char *_data)
{
int Len=strlen(_data);
data=new char[Len];
memcpy(data,_data,Len);
cout<<data<<endl;
cout<<_T("调用带参构造函数 memcpy")<<endl;
}
~ObjA()
{
if (data)
{
cout<<data<<endl;
delete[] data;
data=NULL;
cout<<"delete memory data"<<endl;
}
cout<<_T("调用析构函数.")<<endl;
}
//拷贝赋值
ObjA& operator=(const ObjA &b)
{
int Len=strlen(b.data);
data=new char[Len];
memcpy(data,b.data,Len);
cout<<_T("调用operator = 函数. memcpy")<<endl;
return *this;
}
ObjA(const ObjA &b)
{
cout<<_T("调用拷贝构造函数. memcpy")<<endl;
if (this!=&b)
{
int Len=strlen(b.data);
data=new char[Len];
memcpy(data,b.data,Len);
}
}
//Move拷贝构造函数
ObjA(ObjA &&b)
{
cout<<"Move拷贝构造函数"<<endl;
if (this!=&b)
{
data=b.data;
b.data=NULL;
}
}
//Move赋值拷贝
ObjA& operator=(ObjA &&b)
{
cout<<_T("Move operator = 函数.")<<endl;
if (this!=&b)
{
data=b.data;
b.data=NULL;
}
return *this;
}
char *data;
};
ObjA testRValue_ChangeStr(ObjA o)
{
delete[] o.data;
char *tmp="string after change";
int Len=strlen(tmp);
o.data=new char[Len];
memcpy(o.data,tmp,Len);
return o;
}
int _tmain(int argc, _TCHAR* argv[])
{
//实现了Move拷贝和Move赋值函数.即只移动内部指针,不移动数据.
ObjA a("obj A");
ObjA b("obj B");
b=testRValue_ChangeStr(a);
//由于text...函数返回的是个临时对象,即右值
//所以ObjA的 ObjA& operator=(ObjA &&b)函数被调用.
//b Move拷贝了testRVa...函数返回的临时对象的数据.
//test vector
vector<ObjA> *v=new vector<ObjA>;
//push_back每调用一次,就会调用Move拷贝构造函数
//把旧内存里的对象移至新分配的内存里去.
v->push_back(*new ObjA("C"));
v->push_back(*new ObjA("D"));
v->push_back(*new ObjA("E"));
//以上总共调用了三次memcpy函数,移动数据
return 0;
}








网友评论