移动语义

先看个例子:

vector<string> v1(1000000);//v1存放着100W个string,假设每个string长度为1000
vector<string> v2=copyVector(v1);//使用v1初始化v2

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

#include <iostream>  
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!" << endl;
        pi = &data;
    }
    A(const A &a) {
        data = a.data;
        cout << "copy constructor!" << endl;
        pi = &data;
    }

    A(A &&a) {
        cout << "move constructor!" << endl;
        //直接移动a.pi到pi  
        pi = a.pi;
        data = a.data;
        //修改源pi  
        a.pi = nullptr;
        a.data = 0;
    }
    //A(A &&a)=delete;  
    A operator+(const A &a) {
        A temp(data + a.data);
        cout << endl << "operator+ called!show temp!" << endl;
        temp.show();
        cout << endl;
        return temp;
    }
    void show()const {
        cout << "pi=" << pi << "   data=" << data << endl;
    }
};
int main() {
    int i = 99;
    A a(10);
    a.show();
    A b(i);
    b.show();
    A c(b);
    c.show();
    b + c;
//  A d(b + c);
    cout << "show d!" << endl;
//  d.show();
}

结果:
这里写图片描述
如果修改函数A operator+(const A &a)为以下代码:

    void operator+(const A &a) {
        A temp(data + a.data);
        cout << endl << "operator+ called!show temp!" << endl;
        temp.show();
        cout << endl;
        //return temp;
    }

则出现以下结果:
这里写图片描述
调试分析代码可知,在return temp;这一句执行之前将要调用A(A&&)这个构造函数。
使用拷贝构造函数和移动构造函数的区别:
(1)使用深层拷贝构造函数

返回时构造临时对象,动态分配临时对象返回到主调函数,然后删除临时对象。

(2)使用移动构造函数

将要返回的局部对象转移到主调函数,省去了构造和删除临时对象的过过程。

如果将函数A operator+(const A &a)注释掉,会出现如下结果:
这里写图片描述
参考博客:http://blog.csdn.net/niteip/article/details/37814483

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值