1. 程式人生 > >43.StrVec類:std::move呼叫移動建構函式的一個例項

43.StrVec類:std::move呼叫移動建構函式的一個例項

自定義一個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;
}