智能指针(二)--练习
智能指针--练习
#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;
}
(。・∀・)ノ