43.StrVec類:std::move呼叫移動建構函式的一個例項
阿新 • • 發佈:2018-11-02
自定義一個strvec類,在記憶體不夠,開闢新的記憶體存放元素的時候(也即是reallocate),使用移動操作!而非拷貝!
using namespace std; class strvec { private: static allocator<string>alloc; void chk_n_alloc() { if (size() == capacity()) reallocate(); } void reallocate(); pair<string*, string*> alloc_n_copy(const string*, const string*); void free(); string* elements; string* first_free; string* cap; public: strvec() :elements(nullptr), first_free(nullptr), cap(nullptr) {} strvec(const strvec&); strvec& operator=(const strvec&); ~strvec(); void push_back(const string*); size_t size() const { return first_free - elements; } size_t capacity()const { return cap - elements;} string* begin() const { return elements; } string* end() const { return first_free; } }; void strvec::push_back(const string*s) { chk_n_alloc(); alloc.construct(first_free++, s); } pair<string*, string*> strvec::alloc_n_copy(const string*a, const string*b) { auto data = alloc.allocate(b - a); return{ data,uninitialized_copy(a,b,data) }; } void strvec::free() { if (elements) { for (auto p = first_free; p != elements;) alloc.destroy(p--); alloc.deallocate(elements, cap - elements); } } strvec::strvec(const strvec&s) { auto newdata = alloc_n_copy(s.begin(), s.end()); elements = newdata.first; first_free = cap = newdata.second; } strvec::~strvec() { free(); } strvec& strvec::operator=(const strvec&s) { auto data = alloc_n_copy(s.begin(), s.end()); free(); elements = data.first; cap = first_free = data.second; return *this; } void strvec::reallocate() { auto newcap = size() ? 2 * size() : 1; auto newdata = alloc.allocate(newcap); auto dest = newdata; auto elem = elements; for (size_t i = 0; i != size(); i++) { alloc.construct(dest++, std::move(*elem++)); } free(); elements = newdata; first_free = dest; cap = elements + newcap; }