智能指针(二)--练习

智能指针--练习

#include<iostream>
#include<string>
#include<vector>
#include<memory>
#include<fstream>
#include<initializer_list>
using namespace std;
class StrBlobPtr; //仅仅是声明,在该类为完全定义完整之前,只能使用其类型,而不能调用其成员和函数
class StrBlob {
	friend class StrBlobPtr;
public:
	typedef vector<string>::size_type size_type;
	StrBlob();
	StrBlob(initializer_list<string>il);
	StrBlob(vector<string>stp);
	StrBlob(shared_ptr<vector<string>>tp);
	size_type size() const { return data->size();};
	bool empty()const { return data->empty(); }
	//add & delete
	void push_back(const string& t) { data->push_back(t); }
	void pop_back();
	//visit data
	string& front();
	string& front()const;
	string& back();
	string& back()const;
	//begin和end,返回指向自身的StrBlobPtr,此时不能被定义,直到strBlobPtr被定义完了之后才行,否则C2027
	StrBlobPtr begin();
	StrBlobPtr end();
	StrBlobPtr begin()const;// const版本使得StrBlobPtr可以指向const的StrBlob
	StrBlobPtr end()const; 
private:
	shared_ptr<vector<string>>data;
	//check the index of data
	void check(size_type i, const string& msg)const;
};
StrBlob::StrBlob():data(make_shared<vector<string>>()) {}
StrBlob::StrBlob(initializer_list<string>il):
	data(make_shared<vector<string>>(il)) {}
StrBlob::StrBlob(vector<string> stp):
	data(make_shared<vector<string>>(stp)){}
StrBlob::StrBlob(shared_ptr<vector<string>> tp):data(tp){}
void StrBlob::check(size_type i, const string& msg)const
{
	if (i >= data->size())
		throw out_of_range(msg);
}
string& StrBlob::front()
{
	check(0, "front on the empty Strblob");
	return data->front();
}
string& StrBlob::front()const
{
	check(0, "front on the empty Strblob");
	return data->front();
}
string& StrBlob::back()
{
	check(0, "back on the empty Strblob");
	return data->back();
}
string& StrBlob::back()const 
{
	check(0, "back on the empty Strblob");
	return data->back();
}
void StrBlob::pop_back()
{
	check(0, "pop_back on the empty Strblob");
	return data->pop_back();
}
class StrBlobPtr {
public:
	StrBlobPtr() :curr(0) {}
	StrBlobPtr(StrBlob &a,size_t sz=0):curr(sz),wptr(a.data) {}
	StrBlobPtr(const StrBlob& a, size_t sz = 0) :curr(sz), wptr(a.data) {}
	string& deref()const;//解引用获取元素
	StrBlobPtr& incr();  //前缀递增
	StrBlobPtr& decr();  //递减
	bool equal(const StrBlobPtr& , const StrBlobPtr& );
private:
	//如果检查成功,就check返回一个指向vector的shared_ptr
	shared_ptr<vector<string>> check(size_t, const string&)const;
	//保存一个weak_ptr,意味着底层vector可能被销毁
	weak_ptr<vector<string>>wptr;
	size_t curr;//在数组中当前的位置
};
shared_ptr<vector<string>> StrBlobPtr::check(size_t i , const string& msg)const {
	auto ret = wptr.lock(); //查看是否vector还存在
	if (!ret)
		throw runtime_error("unbound StrBlobPtr");
	if (i >= ret->size())
		throw out_of_range("msg");
	return ret;		//否则返回指向vector的shared_ptr
}
string& StrBlobPtr::deref()const {
	//调用check,检查vector是否安全以及curr是否在范围内
	auto p = check(curr, "dereference past end");
	return (*p)[curr];		//解引用p获得vector,然后使用下标操作提取并返回curr位置上的元素
}
StrBlobPtr& StrBlobPtr::incr(){
	//如果curr已经指向容器的尾后位置,则不能引用它
	check(curr, "increment past end of StrBlobPtr");
	++curr;//推进当前位置
	return *this;
} 
StrBlobPtr& StrBlobPtr::decr()
{
	--curr;       
	check(-1, "decrement past begin of StrBlobPtr");
	return *this;
}
bool StrBlobPtr::equal(const StrBlobPtr& beg, const StrBlobPtr& end)
{

	auto b = beg.wptr.lock(), e = end.wptr.lock();
	if (beg.curr == end.curr)
		return true;
	else
		return false;
}
StrBlobPtr StrBlob::begin()
{
	return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
	auto ret = StrBlobPtr(*this, data->size());
	return ret;
}
StrBlobPtr StrBlob::begin()const
{
	return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()const
{
	auto ret = StrBlobPtr(*this, data->size());
	return ret;
}
void readline(string ifile, vector<string> &str) {//将文件内容读入到一个string的vector容器中去
	vector<string>::iterator it;
	string tmp;
	str.clear();
	ifstream openfile(ifile + ".txt", ifstream::in);  //以读模式打开一个文件									  
	while (getline(openfile, tmp)) {		//没有到达文件的尾部
				//读入一行
		str.push_back(tmp);			//每一行作为独立元素存入vector中
	}
	if (str.empty()) {				//没有数据,直接返回
		cout << "No data?!" << endl;
		return;
	}
	/*
	it = str.begin();
	for (; it != str.end(); it++)	//输出文件内容(存入vector中的)
		cout << (*it) << endl;
	*/
	openfile.close();				//关闭文件流
}
auto init_vec() {
	auto p = new vector<int>;
	return p;
}
auto init_vec_shared() {
	auto p = make_shared<vector<int>>();
	return p;
}
auto read_vec(istream&in ,vector<int>* p) {
	int tmp = 0;
	while (in>>tmp) {		
		p->push_back(tmp);
	}
	return p;
}
auto read_vec_shared(istream& in, shared_ptr<vector<int>>p) {
	int tmp = 0;
	while (in >> tmp) {
		p->push_back(tmp);
	}
	return p;
}
void dis_vec(vector<int>* p) {
	for (auto i = p->begin(); i != p->end(); i++) {
		cout << *i << endl;
	}
	delete p;
}
void dis_vec_shared(shared_ptr<vector<int>>p) {
	for (auto i = p->begin(); i != p->end(); i++) {
		cout << *i << endl;
	}
}
void process(shared_ptr<int>ptr) {
	cout << *ptr << endl;
}
int main(void) {

	//dis_vec(read_vec(cin, init_vec()));  从键盘读入,然后输出
	//dis_vec_shared(read_vec_shared(cin, init_vec_shared())); 从键盘读入,然后输出

	//从文件读入,然后输出
	vector<string>st;
	readline("test", st);
	StrBlob a(st);
	StrBlobPtr b(a.begin());
	while (!b.equal(b,a.end())) {
		cout << b.deref() << endl;
		b.incr();
	}
	return 0;
}
原文地址:https://www.cnblogs.com/FlyerBird/p/12336861.html