C++11:右值引用和转移赋值

版权声明:本文为博主原创文章,未经博主允许不得转载。(注:如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明) https://blog.csdn.net/zgaoq/article/details/86562338

1、左值与右值的区别:

左值:能别赋值的值;能取到地址的值,用&能取到地址,具有持久性;

右值:临时变量;不能用&取到地址;只是字面常量值

2、右值引用

一般用的是左值引用,用&标识

右值引用通过&&获得,只能绑定到将要销毁的对象

如下例子:在代码里面进行了标识:

 

class MemoryBlock {

public:

    //构造器

    explicit MemoryBlock(int length) : length_(length), data_(new int[length]()) {

    }

 

    virtual ~MemoryBlock() {

        if (data_) {

            delete[] data_;

            data_ = nullptr;

        }

    }

    //拷贝构造,左值引用

    MemoryBlock(const MemoryBlock &src) : length_(src.length_), data_(new int[src.length_]()){

        std::copy(src.data_, src.data_+length_, data_);

    }

 

     //普通的赋值,左值引用

    MemoryBlock& operator=(const MemoryBlock &src) {

        if (this != &src) {

            delete[] data_;

 

            length_ = src.length_;

            data_ = new int[length_]();

            std::copy(src.data_, src.data_+length_, data_);

        }

        return *this;

    }

 

    //移动构造器,右值引用

    MemoryBlock(MemoryBlock&& src) : length_(src.length_),data_(src.data_) noexcept  {

        src.length_ = 0;

        src.data_ = nullptr;

    }

 

    //移动赋值

    MemoryBlock& operator=(MemoryBlock &&src) noexcept  {

        if (this != &src) {

            delete[] data_;

 

            length_ = src.length_;

            data_ = src.data_;

 

            //将传入的参数设置为空 释放传入的数据

            src.length_ = 0;

            src.data_ = nullptr;

        }

        return *this;

    }

 

private:

    int length_;

    int *data_;

};

 

MemoryBlock f() {

    return MemoryBlock(50);

}

 

int main()

{

    std::cout << "11111111" << std::endl;

    MemoryBlock a = f();    // 调用构造器

    MemoryBlock b = a;      //拷贝构造

    MemoryBlock c = std::move(a);// 移动构造器,移动语义

    a = f();    // 调用移动赋值运算符,移动语义

    b = a;      // 调用赋值运算符

    c = std::move(a); // 调用移动赋值运算符,移动语义

 

    return 0;

}

    //移动构造器

    MemoryBlock(MemoryBlock&& src) : length_(src.length_),data_(src.data_)  noexcept {

        src.length_ = 0;

        src.data_ = nullptr;

    }

  1. 、将入参传给成员
  2. 、释放传入的数据.

总结:移动构造、移动赋值仅仅是将原来存在的资源移动到其他的位置。因此其自身的资源将会被释放。

猜你喜欢

转载自blog.csdn.net/zgaoq/article/details/86562338
今日推荐