c++_primer_exercise_121920

本文深入探讨了C++中智能指针和模板技术的应用,通过具体实例展示了如何使用`shared_ptr`和`weak_ptr`进行资源管理,以及如何在模板类中实现通用的容器操作。

Str_blob && Str_blob_ptr

/****************************************
 * IDE: VS2010
 ****************************************/
#include 
using std::shared_ptr; using std::make_shared; using std::weak_ptr;

#include 
using std::vector;

#include 
using std::string;

#include 
using std::out_of_range; using std::runtime_error;

#include 
using std::begin; using std::end;

#include 
using std::cin; using std::cout; using std::endl;

// forward declaration
class Str_blob_ptr;

// class I define usually begin with an uppercase letter.
// class Str_blob should be defined in Str_blob.h,
// and implemented in Str_blob.cpp.
class Str_blob	
{
	friend class Str_blob_ptr;
public:
	typedef vector::size_type size_type;
	
	// constructors
	Str_blob() : data(make_shared>()) { }
	Str_blob(string *b, string *e); 

	// size operation
	size_type size() const { return data->size(); }
	bool empty() const { return data->empty(); }

	// add and remove elements
	void push_back(const string &t) { data->push_back(t); }
	void pop_back();

	// element access
	string &front();
	string &back();

	// interface to Str_blob_ptr
	Str_blob_ptr begin();
	Str_blob_ptr end();
private:
	shared_ptr> data;
	// throw msg if data[i] isn't valid
	void check(size_type i, const string &msg) const;
};

// constructor
inline Str_blob::Str_blob(string *b, string *e) :
	data(make_shared>(b, e)) { }

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

// Str_blob_ptr throws an exception on attempts to access a nonexistent element
class Str_blob_ptr
{
	friend bool eq(const Str_blob_ptr &, const Str_blob_ptr &);
public:
	Str_blob_ptr() : curr(0) { }
	Str_blob_ptr(Str_blob &a, size_t sz = 0) :
	wptr(a.data), curr(sz) { }

	string &deref() const;
	Str_blob_ptr &incr();	// prefix version
	Str_blob_ptr &decr();	// prefix version

private:
	// check returns a shared_ptr to the vector if the check succeeds
	shared_ptr> check(size_t, const string &) const;

	// store a weak_ptr, which means the underlying vector might be destroyed
	weak_ptr> wptr;
	size_t curr;		// current position within the array
};

string &Str_blob::front()
{
	// if the vector is empty, check will throw
	check(0, "front on empty Str_blob");
	return data->front();
}

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

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


inline 
shared_ptr> 
Str_blob_ptr::check(size_t i, const string &msg) const
{
	auto ret = wptr.lock();
	if (!ret)
	{
		throw runtime_error("unbound Str_blob_ptr");
	}

	if (i >= ret->size())
	{
		throw out_of_range(msg);
	}

	return ret;
}


inline string &Str_blob_ptr::deref() const
{
	auto p = check(curr, "dereference past end");
	return (*p)[curr];
}

// prefix: return a reference to the increment object
inline Str_blob_ptr &Str_blob_ptr::incr()
{
	// if curr already points past the end of the container, can't increment it
	check(curr, "increment past end of Str_blob_ptr");
	++curr;
	return *this;
}

inline Str_blob_ptr &Str_blob_ptr::decr()
{
	// if curr is zero, decrementing it will yield an invalid subscript
	--curr;
	check(-1, "decrement past begin of Str_blob_ptr");
	return *this;
}


// begin and end members for str_blob
inline Str_blob_ptr Str_blob::begin()
{
	return Str_blob_ptr(*this);
}

inline Str_blob_ptr Str_blob::end()
{
	Str_blob_ptr ret = Str_blob_ptr(*this, data->size());
	return ret;
}

inline bool eq(const Str_blob_ptr &lhs, const Str_blob_ptr &rhs)
{
	auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
	if (l == r)
	{
		// then they're equal if they're both null or
		// if they point to the same element
		return (!r || lhs.curr == rhs.curr);
	}
	else
	{
		return false;
	}
}

inline bool neq(const Str_blob_ptr &lhs, const Str_blob_ptr &rhs)
{
	return !eq(lhs, rhs);
}

int main(void)
{
/*	Str_blob b1;
	{
		string temp[] = { "a", "an", "the" };
		Str_blob b2(begin(temp), end(temp));
		b1 = b2;
		b2.push_back("about");
		cout << b2.size() << endl;
	}
	cout << b1.size() << endl;*/
	Str_blob b1;
	string word;
	while (cin >> word)
	{
		b1.push_back(word);
	}

 	for (Str_blob_ptr it = b1.begin(); neq(it, b1.end()); it.incr())
	{
		cout << it.deref() << endl;
	}

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值