现在 是 第十二章的部分练习:
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]; }
你认为那个版本更好?为什么?
原版本是:
很明显,当然是 第一个版本好,显而易见,第一个版本 可读性比较好,第二个版本 咋一看 还不知道 不什么,要理清优先级,然后check返回一个shared_ptr指针再解引用,之后是下标运算获取元素,而第一版则 轻易看出 check 函数返回一个 指针 ,然后返回 解引用的元素。std::string & deref()const { auto p = check(curr,"dereference past end"); return (*p)[curr]; }
12.22:
为了能让StrBlobPtr使用const StrBlob,你觉得应该如何修改?定义一个名为ConstStrBlobPtr的类,使其能够指向const StrBlob。
第一个问题 以我的方法就是 直接添加一个 接受 初始值是 const strblob 的构造函数,所以是:
直接再 StrBlobPtr 类里 加上这个成员函数。StrBlobPtr(const StrBlob & a, std::size_t sz = 0) :wptr(a.data), curr(sz) {}
第二个问题 则是直接定义一个 构造函数 是上面的 构造函数的ConstStrBlobPtr类,是不是错了 ( ̄▽ ̄)" 不知道 不过挺好的。 望指出。
上面 就这样 ,也需要 关联 StrBlob类 作为 友元类,这点应该难不倒你们哈,你们自己搞哈 ,我 就。。。。溜了溜了。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; }
以上,如果错了 ,望大家提出。(+_+)?