C++ Primer 练习12.1.1 & 12.1.6

12.1.1

#include<iostream>
#include<fstream>
#include<vector>
#include<memory>
#include<string>
using namespace std;

class StrBlob {
public:
	typedef vector<string>::size_type size_type;
	
	StrBlob() : data(make_shared<vector<string>>()) {}
	StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}
	
	size_type size() const { return data->size(); }
	bool empty() const { return data->empty(); }
	void push_back(const string& t) { data->push_back(t); }
	void pop_back();
	string& front();
	const string& front() const;
	string& back();
	const string& back() const;
	
private:
	shared_ptr<vector<string>> data;
	void check(size_type i, const string& smg) const;
};

int main(int argc, char* argv[])
{
	StrBlob d({ "2020,7,13", });
	cout << d.size() << endl;
	d.push_back("2020,7,14");
	cout << d.size() << endl;
	d.pop_back();
	cout << d.size() << endl;
	return 0;
}

void StrBlob::check(size_type i, const string& msg) const
{
	if (i >= data->size())
		throw out_of_range(msg);
}

void StrBlob::pop_back()
{
	check(0, "pop_back on empty StrBlob");
	return data->pop_back();
}

string&
StrBlob::front()
{
	check(0, "front on empty StrBlob");
	return data->front();
}
const string&
StrBlob::front() const
{
	check(0, "front on empty StrBlob");
	return data->front();
}

string&
StrBlob::back()
{
	check(0, "back on empty StrBlob");
	return data->back();
}

const string&
StrBlob::back() const
{
	check(0, "back on empty StrBlob");
	return data->back();
}

12.1.6

head.h

#include <memory>
#include <vector>
#include <string>

class StrBlobPtr;	//友元必须提前声明
class StrBlob {
	friend class StrBlobPtr;
public:
	typedef std::vector<std::string>::size_type size_type;
	
	StrBlob() :data(std::make_shared<std::vector<std::string>>()) { }
	StrBlob(std::initializer_list<std::string>il) :data(std::make_shared<std::vector<std::string>>(il)) { }
	
	size_type size() const { return data->size(); }
	bool empty() const { return data->empty(); }
	void push_back(const std::string& t) { data->push_back(t); }
	void pop_back();
	std::string& front();
	std::string& back();
	const std::string& front() const;
	const std::string& back() const;
	
	StrBlobPtr begin();
	StrBlobPtr end();
	StrBlobPtr cbegin() const;
	StrBlobPtr cend() const;
	
private:
	std::shared_ptr<std::vector<std::string>> data;
	void check(size_type i, const std::string& msg) const;
};

class StrBlobPtr {
public:
	StrBlobPtr() : curr(0) { }
	StrBlobPtr(const StrBlob& a, size_t sz = 0) :
		wptr(a.data), curr(sz) { }
		
	bool operator != (const StrBlobPtr& q) { return q.curr != curr; }
	std::string& deref() const;
	StrBlobPtr& incr();
	
private:
	std::shared_ptr<std::vector<std::string>>
		check(std::size_t i, const std::string& msg) const;
	std::weak_ptr<std::vector<std::string>> wptr;
	std::size_t curr;
};

void StrBlob::pop_back()
{
	check(0, "pop_back on empty StrBlob");
	data->pop_back();
}

std::string& 
StrBlob::front()
{
	check(0, "front on empty StrBlob");
	return data->front();
}

std::string& 
StrBlob::back()
{
	check(0, "back on empty StrBlob");
	return data->back();
}

const std::string& 
StrBlob::front() const
{
	check(0, "front on empty StrBlob");
	return data->front();
}

const std::string&
StrBlob::back() const
{
	check(0, "back on empty StrBlob");
	return data->back();
}

void StrBlob::check(size_type i, const std::string& msg) const
{
	if (i >= data->size())
		throw std::out_of_range(msg);
}

StrBlobPtr StrBlob::begin()
{
	return StrBlobPtr(*this);
}

StrBlobPtr StrBlob::end()
{
	auto ret = StrBlobPtr(*this, data->size());
	return ret;
}

StrBlobPtr StrBlob::cbegin() const
{
	return StrBlobPtr(*this);
}

StrBlobPtr StrBlob::cend() const
{
	auto ret = StrBlobPtr(*this, data->size());
	return ret;
}

std::string& 
StrBlobPtr::deref() const
{
	auto p = check(curr, "dereferemce past end");
	return (*p)[curr];
}

StrBlobPtr& 
StrBlobPtr::incr()
{
	check(curr, "increment past end of StrBlobPtr");
	++curr;
	return *this;
}

std::shared_ptr<std::vector<std::string>> 
StrBlobPtr::check(std::size_t i, const std::string& msg) const
{
	auto ret = wptr.lock();
	if (!ret)
		throw std::runtime_error("unbound StrBlobPtr");
	if (i >= ret->size())
		throw std::out_of_range(msg);
	return ret;
}

cpp

#include<iostream>
#include<memory>
#include"head.h"

using namespace std;

int main(int argc, char* argv[])
{
    const StrBlob b{ "It", "is", "a", "Test" };
    StrBlobPtr q(b);
    for (q = b.cbegin(); q != b.cend(); q.incr())
        cout << q.deref() << " ";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dzx1025/article/details/107213803
今日推荐