题目:
练习12.19:定义你自己版本的StrBlobPtr,更新StrBlob类,加入恰当的
friend声明及begin和end成员。
练习12.20:编写程序,逐行读入一个输入文件,将内容存入一个
StrBlob中,用一个StrBlobPtr打印出StrBlob中的每个元素。
难点
1.最开始分成两个头文件去写,导致重复声明了
2.StrBlob的默认构造函数没有对data进行构造,导致其没有容量,一添加就出错。
4. 一个头文件声明两个类,需要先声明后定义,而相关函数,需要在类定义以后再进行定义。
3. 需要重载运算符,不然StrBlobPtr无法进行比较。
#ifndef STRBLOB_H_
#define STRBLOB_H_
#include<iostream>
#include<vector>
#include<string>
#include<memory>
using namespace std;
class StrBlobPtr;
class StrBlob
{
public:
using size_type = vector<string>::size_type;
StrBlob() :data(make_shared < vector<string>>()){};
StrBlob(initializer_list<string>il):
data(make_shared<vector<string>>(il)){}
size_type getSize() const
{
return data->size();
}
bool empty()const {
return data->empty();
}
void push_back(const string& str);
void pop_back() ;
const string& front()const;
const string& back()const;
StrBlobPtr begin();
StrBlobPtr end();
private:
shared_ptr<vector<string>>data; //现在是指针了
bool check(size_type size, const string& str)const;
friend class StrBlobPtr;
};
class StrBlobPtr
{
public:
StrBlobPtr() :curr(0) {}
StrBlobPtr(StrBlob& a, size_t sz = 0) :wptr(a.data), curr(sz) {}
bool operator!=(const StrBlobPtr& p) { return p.curr != curr; }
string& deref()const;
StrBlobPtr& incr();
private:
weak_ptr<vector<string>>wptr;
size_t curr;
shared_ptr<vector<string>> check(size_t sz, const string& msg) const;
};
inline shared_ptr<vector<string>>
StrBlobPtr::check(size_t sz, const string& str)const
{
auto ret = wptr.lock();
if (!ret)
{
throw runtime_error("unbound StrBlobPtr");
}
if (sz >= ret->size())
{
throw out_of_range(str);
}
return ret;
}
//返回vector中的最后一个元素
inline string&
StrBlobPtr::deref()const
{
auto p = check(curr, "out_of_range");
return (*p)[curr];
}
//前缀递增
inline StrBlobPtr&
StrBlobPtr::incr()
{
auto p = check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
inline bool
StrBlob::check(size_type size, const string& msg)const
{
if (!size)
{
throw out_of_range(msg);
return false;
}
return true;
}
inline void
StrBlob::push_back(const string& str)
{
return (*data).push_back(str);
}
inline void
StrBlob::pop_back()
{
if (check(data->size(), "容器为空,弹出失败!"))
{
data->pop_back();
cout << "弹出成功" << endl;
}
}
inline const string&
StrBlob::front()const
{
if (check(data->size(), "容器为空,查看头元素失败!"))
{
return data->front();
}
}
inline const string&
StrBlob::back()const
{
if (check(data->size(), "容器为空,查看为元素失败!"))
{
return data->back();
}
}
inline StrBlobPtr
StrBlob::begin()
{
return StrBlobPtr(*this);
}
inline StrBlobPtr
StrBlob::end()
{
auto ret = StrBlobPtr(*this, data->size());
return ret;
}
#endif STRBLOB_H_