C++11新特性之move与forward

  1、左值与右值

  一个备选的定义(有争议的地方):左值是可以用取址运算符&取得其内存地址的表达式;不是左值的表达式则为右值。

 

  2、move:返回arg的右值引用

template <class T>
typename remove_reference<T>::type&& move (T&& arg) noexcept;

  示例:

class MemoryBlock 
{
public:
    explicit MemoryBlock(size_t length) : _length(length), _data(new int[length]) 
    {
        cout << "In constructor. length = " << _length << endl;
    }

    ~MemoryBlock()
    {
        cout << "In destructor. length = " << _length << endl;

        if (_data != NULL)
            delete[] _data;
    }

    // 拷贝构造函数
    MemoryBlock(const MemoryBlock &other) : _length(other._length), _data(new int[other._length])
    {
        cout << "In copy constructor length = "    << other._length << endl;

        copy(other._data, other._data + _length, _data);
    }

    // (拷贝)赋值操作符
    MemoryBlock &operator=(const MemoryBlock &other)
    {
        cout << "In copy assignment operator. length = " << other._length << endl;

        if (this != &other)
        {
            delete[] _data;

            _length = other._length;
            _data = new int[_length];
            copy(other._data, other._data + _length, _data);
        }

        return *this;
    }

    // Move构造函数。直接“窃取”other._data的指针,而不是拷贝other._data,提高了效率
    MemoryBlock(MemoryBlock &&other) : _length(0), _data(NULL)
    {
        cout << "In move constructor. length = " << other._length << endl;

        _data = other._data;
        _length = other._length;
        other._data = NULL;
        other._length = 0;
    }

    // Move赋值操作符
    MemoryBlock &operator=(MemoryBlock &&other)
    {
        cout << "In move assignment operator. length = " << other._length << endl;

        if (this != &other)
        {
            delete[] _data;

            _data = other._data;
            _length = other._length;
            other._data = NULL;
            other._length = 0;
        }

        return *this;
    }
private:
    size_t _length;
    int *_data;
};

int main()
{
    vector<MemoryBlock> v;
    // 这里"MemoryBlock(25)"是一个非常量右值,是一个临时的、可修改的对象
    // 因此push_back的时候调用了Move构造函数,“篡改”了它
    v.push_back(MemoryBlock(25));

    MemoryBlock mb(111);
    // mb为左值,如果确定不再需要它,下面的语句可用v.push_back(std::move(mb));代替
    // 代替之后,push_back的时候由使用Copy构造函数变为使用Move构造函数
    v.push_back(mb);
    cout << "======================" << endl;

    return 0;
}

 

  参考资料:

  http://www.cplusplus.com

  https://segmentfault.com/a/1190000003004734?_ea=266751#articleHeader5

  http://www.stroustrup.com/C++11FAQ.html#rval

 

 

不断学习中。。。

posted on 2016-02-15 20:18  han'er  阅读(562)  评论(0编辑  收藏  举报

导航