设为首页 加入收藏

TOP

C++11 新特性(2) 移动语义
2015-07-24 05:38:23 来源: 作者: 【 】 浏览:6
Tags:特性 移动 语义

C++11支持移动语义。

一:为什么需要移动语义和什么是移动语义

我们先来看看C++11之前的复制过程。假设有下列代码:

vector v1(1000000);//v1存放着100W个string,假设每个string长度为1000

vector v2(v1);//使用v1初始化v2

vector和string类都使用动态内存分配,因此他们必须定义使用他们自己的new版本的复制构造函数。

复制构造函数vector 将使用new给1000W个string分配对象,而每个string 将使用new给每个string分配1000个字符的空间大小。接下来全部的都将从v1中逐个复制string到v2中,这里的工作量非常大,但是并没有问题。

但真的没有问题吗?有时候答案是否定的。例如,假设有一个函数,他返回一个vector 对象。

vector copyVector(const vector &v){

vector temp;

//复制100W个string到temp

return temp;

}

接下来,以以下方式调用这个函数。

vector v1(1000000);//v1存放着100W个string,假设每个string长度为1000

vector v2=copyVector(v1);//使用v1初始化v2

构造v2的时候,编译器先利用v1构造生成了一个temp副本,然后将temp复制给一个临时对象,返回给v2,v2利用该临时对象,构造自己。

这将导致非常巨大的工作量!做了大量的无用功(将temp复制给一个临时对象,返回给v2,v2利用该临时对象,构造自己)。在这之后,temp这个临时的对象被删除了,返回的那个temp副本临时对象也被删除了,如果编译器能够将temp的所有权直接转移给v2不是更好吗?也就是说,不用将100W个string多次复制到新的地方,再删除原来的字符,而是直接保留字符,并将v2与之关联。这类似于计算机中文件的移动。实际文件还保留在原来的地方,而只是记录修改了,这种方法称之为移动语义。

移动语义避免了移动原始数据,而只是修改了记录。

要实现移动语义,必须让编译器知道什么时候需要复制,什么时候不需要复制。这就是右值引用发挥最大作用的地方。


二:如何实现移动语义

看一个简单的使用移动语义的例子。

#include 
  
   
using namespace std;
class A{
private:
	int data;//data
	int *pi;//point to data
public:
	//禁止隐式转换
	A(){
	}
	explicit A(int i):data(i){
		cout<<"normal constuctor1!"<
    
    

	A(const A &a){
		data=a.data;
		cout<<"copy constructor!"<
     

      



\

看出来什么问题没有?

对,好像并没有调用移动构造函数!<??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+tavKx9PQw7vT0Leiz9YhdGVtcLrNZLXEcGm2vMrH1rjP8s2s0ru49rXYt73Ex7j2P9XiysfKssO0x+m/9j88L3A+CjxwPtStwLTKx9LyzqpHQ0PX1LT4tcTT0iYjMjA1NDA70+/S5SE8L3A+CjxwPtKyvs3Kxyyx4NLrxvdHQ0O74bDvxOPX1Lav08W7ryE8L3A+CjxwPrK70MXH67+0z8LD5sD919MhztLDx8D708NDJiM0MzsmIzQzOzExtcRkZWxldGXM2NDUITwvcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">#include using namespace std; class A{ private: int data;//data int *pi;//point to data public: //禁止隐式转换 A(){ } explicit A(int i):data(i){ cout<<"normal constuctor1!"<
运行结果:


也就是说,在return temp;这一句上将要调用A(A&&)这个构造函数;

但是现在这个函数被我们显式删除了!

b+c也是一个右值!也是需要调用移动构造函数的!

因此上一个例子实际上是调用了移动语义的构造函数!



】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU 4847 陕西邀请赛A(水) 下一篇HDU-2665-Kth number(划分树)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: