现在 是 第十二章的部分练习:
12.19:
定义你自己版本的StrBlobPtr,更新StrBlob类,加入恰当的friend声明及begin和end成员了。
这题 为了方便 我直接写在一个头文件里。
//StrBlob.h
#include <iostream>
#include <memory>
#include<stdexcept>
#include <string>
#include <vector>
using std::cout;
using std::endl;
using std::cin;
class StrBlobPtr;
class StrBlob {
//友元声明
friend class StrBlobPtr;
public:
typedef std::vector<std::string>::size_type size_type;
StrBlob();
StrBlob(std::initializer_list<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;
// begin() 和 end()
StrBlobPtr begin();
StrBlobPtr end();
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(StrBlob &a, std::size_t sz = 0)
: wptr(a.data), curr(sz) {}
std::string & deref() const;
StrBlobPtr& incr();
private:
std::shared_ptr<std::vector<std::string>>
check(std::size_t, const std::string &) const;
std::weak_ptr<std::vector<std::string>> wptr;
std::size_t curr;
};
//strblob 函数外部定义
const std::string & StrBlob::front() const
{
check(0, "out range");
return this->data->front();
}
const std::string &StrBlob::back() const
{
check(0, "out range");
return data->back();
}
StrBlob::StrBlob() :data(std::make_shared<std::vector<std::string>>()) {}
StrBlob::StrBlob(std::initializer_list < std::string> il) :
data(std::make_shared<std::vector<std::string>>(il)) {};
void StrBlob::check(size_type i, const std::string &msg)const
{
if (i >= data->size())
throw std::out_of_range(msg);
}
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();
}
void StrBlob::pop_back()
{
check(0, "pop_back on empty StrBlob");
data->pop_back();
}
StrBlobPtr StrBlob::begin()
{
return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
auto ret = StrBlobPtr(*this, data->size());
return ret;
}
//strblobptr 函数外部定义
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;
}
std::string & StrBlobPtr::deref() const
{
auto p = check(curr,"dereference past end");
return (*p)[curr];
}
StrBlobPtr & StrBlobPtr::incr()
{
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
//主函数
#include "StrBlob.h"
int main(){StrBlob b({ "233","2333","23333" });StrBlobPtr bp(b);bp.incr();cout << bp.deref() << endl;return 0;}
12.20:
编写程序,逐行读入一个输入文件,将内容存入一个StrBlob中,用一个StrBlobPtr打印处StrBlob中的每个元素。
#include "StrBlob.h"
int main()
{
ifstream in_file("text.txt");
StrBlob b;
string t;
StrBlobPtr bp(b);
while (getline(in_file,t))
b.push_back(t);
for (size_t i = 0; i != b.size(); i++)
{
cout << bp.deref() << endl;
bp.incr();
}
in_file.close();
return 0;
}
12.21:
也可以这样编写StrBLobPtr的deref成员:
std::string & deref() const
{ return (*check(curr,"dereference pase end"))[curr]; }
你认为那个版本更好?为什么?
原版本是:
std::string & deref()const
{
auto p = check(curr,"dereference past end");
return (*p)[curr];
}
很明显,当然是 第一个版本好,显而易见,第一个版本 可读性比较好,第二个版本 咋一看 还不知道 不什么,要理清优先级,然后check返回一个shared_ptr指针再解引用,之后是下标运算获取元素,而第一版则 轻易看出 check 函数返回一个 指针 ,然后返回 解引用的元素。
12.22:
为了能让StrBlobPtr使用const StrBlob,你觉得应该如何修改?定义一个名为ConstStrBlobPtr的类,使其能够指向const StrBlob。
第一个问题 以我的方法就是 直接添加一个 接受 初始值是 const strblob 的构造函数,所以是:
StrBlobPtr(const StrBlob & a, std::size_t sz = 0) :wptr(a.data), curr(sz) {}
直接再 StrBlobPtr 类里 加上这个成员函数。
第二个问题 则是直接定义一个 构造函数 是上面的 构造函数的ConstStrBlobPtr类,是不是错了 ( ̄▽ ̄)" 不知道 不过挺好的。 望指出。
class ConstStrBlobPtr
{
public:
ConstStrBlobPtr():curr(0) {}
ConstStrBlobPtr(const StrBlob & a,size_t i = 0) : w(a.data),curr(i) {}
string & deref() const;
ConstStrBlobPtr & incr();
private:
shared_ptr<vector<string>> check(size_t, const string &) const;
weak_ptr<vector<string>> w; //指向一个vector<string>的shared_ptr指针的对象
size_t curr;
};
string & ConstStrBlobPtr::deref() const
{
auto p = check(curr,"wocao");
return (*p)[curr];
}
ConstStrBlobPtr & ConstStrBlobPtr::incr()
{
check(curr, "wocaohhh");
++curr;
return *this;
}
shared_ptr<vector<string>> ConstStrBlobPtr::check(size_t i, const string & msg) const
{
auto pw = w.lock();
if (!pw)
throw std::runtime_error("hhhhh");
if (i >= pw->size())
throw std::out_of_range("xxxxx");
return pw;
}
上面 就这样 ,也需要 关联 StrBlob类 作为 友元类,这点应该难不倒你们哈,你们自己搞哈 ,我 就。。。。溜了溜了。
以上,如果错了 ,望大家提出。(+_+)?