C++ Primer 练习13.5

13. 39~41

StrVec.h

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

class StrVec {
public:
	StrVec() :
		elements(nullptr), first_free(nullptr), cap(nullptr) {}
	StrVec(const initializer_list<string>&);
	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 reserve(size_t sz);
	void resize(size_t, const string& = string());	//声明不要忘记设置缺省值
	void print();
private:
	static allocator<string> alloc;
	void chk_n_alloc() {
		if (size() == capacity()) reallocate();
	}
	pair<string*, string*> alloc_n_copy
	(const string*, const string*);
	void free();
	void reallocate();
	string* elements;
	string* first_free;
	string* cap;
};

StrVec.cpp

#include"test.h"

allocator<string> StrVec::alloc;

StrVec::StrVec(const initializer_list<string>& lst)
{
	elements = alloc.allocate(lst.end() - lst.begin());
	cap = first_free = uninitialized_copy(lst.begin(), lst.end(), 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::operator=(const StrVec& s)
{
	auto newdata = alloc_n_copy(s.begin(), s.end());
	free();
	elements = newdata.first;
	first_free = cap = newdata.second;
	return *this;
}

StrVec::~StrVec()
{
	free();
}

void StrVec::push_back(const string& s)
{
	chk_n_alloc();
	alloc.construct(first_free++, s);
}

void StrVec::reserve(size_t sz)
{
	if (sz > capacity()) {
		auto newdata = alloc.allocate(sz);
		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 + sz;
	}
}

void StrVec::resize(size_t n, const string& s)
{
	if (n == size())
		return;
	if (n < capacity()) {
		if (n > size())
			for (int i = 0; i < n; ++i)
				alloc.construct(first_free++, s);
		else
			for (auto p = first_free; p != elements + n; )
				alloc.destroy(--p);
		first_free = elements + n;
	}
	else {
		this->reserve(n + size());
		for (int i = 0; i < n; ++i)
			alloc.construct(first_free++, s);
	}
}

void StrVec::print()
{
	for (auto i = elements; i != first_free; ++i)
		cout << *i << " ";
}

pair<string*, string*>
StrVec::alloc_n_copy(const string* b, const string* e)
{
	auto data = alloc.allocate(e - b);
	return { data, uninitialized_copy(b,e,data) };
}

void StrVec::free()
{
	if (elements) {	
		//for (auto p = first_free; p != elements; )
		//	alloc.destroy(--p);

		for_each(elements, first_free, [&](string p) {
			alloc.destroy(&p);
			});

		alloc.deallocate(elements, cap - elements);
	}
}

void StrVec::reallocate()
{
	auto newcapacity = size() ? 2 * size() : 1;
	auto newdata = alloc.allocate(newcapacity);
	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 + newcapacity;
}

main.cpp

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include"test.h"
using namespace std;

void test(StrVec& s) {
	cout << endl;
	s.print();
	cout << endl;
	cout << "\tCapacity " << s.capacity() << "\tSize " << s.size() << endl;
}

int main()
{
	initializer_list<string> list{ "First", "test", };
	StrVec s1, s2(list), s3(s2), s4 = s3;
	s1 = s2;

	test(s1);

	s2.push_back("Push_back Test");
	test(s2);

	s3.reserve(25);
	test(s3);

	s4.resize(8, "Resize");
	test(s4);

	s4.resize(3);
	test(s4);

	s4.resize(1, "Resize");
	test(s4);

	return 0;
}

在这里插入图片描述

13.44

String.h

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

class String {
	friend ostream& operator<<(ostream&, const String&);
public:
	String() : element(nullptr), first_free(nullptr) {}
	String(const char* s) {
		size_t sz = strlen(s);
		auto newdata = alloc.allocate(sz);
		auto dest = newdata;
		for (unsigned int i = 0; i != sz; ++i)
			alloc.construct(dest++, s[i]);
		element = newdata;
		first_free = dest;
	}
private:
	static allocator<char> alloc;
	char* element;
	char* first_free;
};

main.cpp

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include"test.h"
using namespace std;

ostream& operator<<(ostream& os, const String& s) {
	auto c = s.element;
	while (c != s.first_free)
		os << *c++;
	return os;
}

int main()
{
	String s1("hello");
	cout << s1 << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Dzx1025/article/details/107524378