移动和复制ctor语义

时间:2017-02-21 12:42:40

标签: c++ move-semantics

#include <iostream>
#include <memory>
using namespace std;

template <typename T>
class vector{
    size_t size_;
    size_t count_;
    T * buffer_;
public:
    vector(size_t sz = 8) : size_(sz), count_(0), buffer_(new T[sz]){
        for(size_t i = 0; i < size_; ++i){
            buffer_[i] = T();
        }
        cout << "default ctor invoked"<< endl;
    }

    //  copy ctor
    vector(const vector<T> & v) : size_(v.size_), count_(0), buffer_(new T[v.size_]){
        for(size_t i = 0; i < size_; ++i){
            buffer_[i] = v.buffer_[i];
            ++count_;
        }

        cout << "copy ctor invoked"<< endl;
    }


    //  move ctor
    vector(vector<T> && v) : size_(v.size_), count_(v.count_), buffer_(v.buffer_){
        v.size_ = size_t();
        v.buffer_ = nullptr;
        cout << "move ctor invoked" << endl;
    }

    vector(const initializer_list<T> & li) : size_(li.size()), count_(0), buffer_(new T[size_]){
        int i = 0;
        for(typename initializer_list<T>::iterator it = li.begin(); it != li.end(); ++it){
            buffer_[i++] = *it;
            ++count_;
        }

        cout << "initializer list ctor" << endl;
    }

    ~vector(){
        delete [] buffer_;
        buffer_ = nullptr;
        size_ = 0;
        count_= 0;
    }

    vector<T> & operator=(const vector<T> &v){
        size_ = v.size_;
        count_ = 0;
        buffer_ = new T[size_]();

        for(size_t i = 0; i < size_; ++i){
            buffer_[i] = v.buffer_[i];
            ++count_;
        }

        cout << "assignment operator" << endl;

        return *this;
    }

    vector<T> & operator=(vector<T> && v){
        size_ = v.size_;
        count_ = v.count_;
        buffer_ = v.buffer_;
        v.buffer_ = nullptr;
        v.size_ = size_t();
        cout << "move assignment operator" << endl;
        return *this;
    }

    T& operator[](size_t index){
        if (index < 0 || index >= size_) throw out_of_range("index is out of vector size");
        return buffer_[index];
    }

    bool is_empty() const{
        return (count_ <= 0);
    }

    const size_t & size() const{
        return size_;
    }

    const size_t & count() const{
        return count_;
    }

    template <typename U>
    friend ostream & operator<<(ostream & , const vector<U> &);
};

template <typename T>
ostream & operator<<(ostream & stream, const vector<T> & v){
    if (v.buffer_ == nullptr || v.count_ <= 0)
        stream << "empty list";
    else{
        stream << "vec: { ";
        for(size_t i = 0; i < v.size_; ++i){
            stream << v.buffer_[i] << " ";
        }
        stream << "}";
    }
    return stream;
}

template <typename T>
vector<T> createVector(size_t sz = 8){
    vector<T> tmp(sz);
    return tmp;//*(new vector<T>(sz));
}

int main(int argc, char ** argv){

    vector<int> vec{1,2,4,7,4,2,1,2,9,12,99,23}, vec2(createVector<int>());

    return 0;
}

我正在研究移动语义。上面我创建了一个包含copy ctor,move ctor,copy assignment和move assignment操作符的向量。在main函数中,我创建了一个名为 vec 的向量,该向量由 initializer_list 构成。我创建了第二个名为 vec2 的向量,它从函数 createVector()中获取临时返回向量。为什么搬家不在这里调用?你能澄清一下情况吗?先感谢您。

0 个答案:

没有答案