C++primer 12.1.6节练习

练习12.19

  1 #include <iostream>
  2 #include <fstream>
  3 #include <string>
  4 #include <sstream>
  5 #include <set>
  6 #include <map>
  7 #include <algorithm>
  8 #include <vector>
  9 #include <algorithm>
 10 #include <iterator>
 11 #include <unordered_map>
 12 #include <memory>
 13 
 14 using namespace std;
 15 
 16 class strBlobPtr {
 17 public:
 18     strBlobPtr() : curr(0) {}
 19     strBlobPtr(strBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}
 20     string & deref() const;
 21     strBlobPtr &incr();
 22 private:
 23     shared_ptr<vector<string>> check(size_t t, const string &str) const;
 24     weak_ptr<vector<string>> wptr;
 25     size_t curr;
 26 };
 27 
 28 class strBlob {
 29     friend void print(strBlob s);
 30     friend class strBlobPtr;
 31 public:
 32     typedef vector<string>::size_type size_type;
 33     strBlob();
 34     strBlob(initializer_list<string> il);
 35     size_type size() const { return data->size(); }
 36     bool empty() const { return data->empty(); }
 37     void push_back(const string &t);
 38     void pop_back();
 39     const string &front();
 40     const string &back();
 41     strBlobPtr begin() { return strBlobPtr(*this); }
 42     strBlobPtr end() { return strBlobPtr(*this, data->size()); }
 43 private:
 44     shared_ptr<vector<string>> data;
 45     void check(size_type i, const string &msg) const;
 46 };
 47 
 48 void print(strBlob s);
 49 
 50 int main()
 51 {
 52     strBlob p1({ "asd", "qew", "jkl" });
 53     print(p1);
 54     p1.push_back("dqw");
 55     print(p1);
 56     p1.pop_back();
 57     p1.pop_back();
 58     print(p1);
 59     cout << endl;
 60     cout << p1.front() << endl;
 61     cout << p1.back() << endl;
 62     system("pause");
 63     return 0;
 64 }
 65 
 66 strBlob::strBlob() : data(make_shared<vector<string>>()) {}
 67 strBlob::strBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}
 68 void strBlob::push_back(const string & t)
 69 {
 70     data->push_back(t);
 71 }
 72 void strBlob::pop_back()
 73 {
 74     check(0, "pop_back on empty StrBlob");
 75     data->pop_back();
 76 }
 77 const string & strBlob::front()
 78 {
 79     check(0, "front on empty StrBlob");
 80     return data->front();
 81     // TODO: 在此处插入 return 语句
 82 }
 83 const string & strBlob::back()
 84 {
 85     check(0, "back on empty StrBlob");
 86     return data->back();
 87     // TODO: 在此处插入 return 语句
 88 }
 89 
 90 
 91 void strBlob::check(size_type i, const string & msg) const
 92 {
 93     if (i >= data->size())
 94         throw out_of_range(msg);
 95 }
 96 
 97 void print(strBlob s)
 98 {
 99     for (auto c : *(s.data))
100         cout << c << endl;
101     cout << endl;
102 }
103 
104 string & strBlobPtr::deref() const
105 {
106     auto p = check(curr, "dereference past end");
107     return (*p)[curr];
108     // TODO: 在此处插入 return 语句
109 }
110 
111 strBlobPtr & strBlobPtr::incr()
112 {
113     check(curr, "increment past end of strBlobPtr");
114     ++curr;
115     return *this;
116     // TODO: 在此处插入 return 语句
117 }
118 
119 shared_ptr<vector<string>> strBlobPtr::check(size_t t, const string & str) const
120 {
121     auto ret = wptr.lock();
122     if (!ret)
123         throw runtime_error("unbound strBlobPtr");
124     if (t >= ret->size())
125         throw out_of_range(str);
126     return ret;
127 }

练习12.20

  1 //my_StrBlob.h
  2 #ifndef MY_STRBLOB_H
  3 #define MY_STRBLOB_H
  4 #include <vector>
  5 #include <string>
  6 #include <memory>
  7 #include <initializer_list>
  8 #include <stdexcept>
  9 using std::vector;
 10 using std::string;
 11 using std::shared_ptr;
 12 using std::make_shared;
 13 using std::weak_ptr;
 14 using std::initializer_list;
 15 using std::runtime_error;
 16 using std::out_of_range;
 17 
 18 // 提前声明,StrBlob中的友类声明所需
 19 class StrBlobPtr;
 20 
 21 class StrBlob {
 22     friend class StrBlobPtr;
 23 public:
 24     typedef vector<string>::size_type size_type;
 25     StrBlob();
 26     StrBlob(initializer_list<string> il);
 27     size_type size() const { return data->size(); }
 28     bool empty() const { return data->empty(); }
 29     // 添加删除元素
 30     void push_back(const string &t) {data->push_back(t); }
 31     void pop_back();
 32     // 元素访问
 33     string& front();
 34     const string& front() const;
 35     string& back();
 36     const string& back() const;
 37 
 38     // 提供给StrBlobPtr的接口
 39     StrBlobPtr begin();    //定义了StrBlobPtr后才能定义这两个函数
 40     StrBlobPtr end();
 41 private:
 42     shared_ptr<vector<string>> data;
 43     // 如果data[i]不合法,抛出一个异常
 44     void check(size_type i, const string &msg) const;
 45 };
 46 
 47 inline StrBlob::StrBlob(): data(make_shared<vector<string>> ()) { }
 48 StrBlob::StrBlob(initializer_list<string> il): data(make_shared<vector<string>> (il)) { }
 49 
 50 inline void StrBlob::check(size_type i, const string &msg) const
 51 {
 52     if (i >= data->size())
 53         throw out_of_range(msg);
 54 }
 55 
 56 inline string& StrBlob::front()
 57 {
 58     check(0, "front on empty StrBlob");
 59     return data->front();
 60 }
 61 
 62 // const版本front
 63 inline const string& StrBlob::front() const
 64 {
 65     check(0, "front on empty StrBlob");
 66     return data->front();
 67 }
 68 
 69 inline string& StrBlob::back()
 70 {
 71     check(0, "back on empty StrBlob");
 72     return data->back();
 73 }
 74 
 75 // const版本back
 76 inline const string& StrBlob::back() const
 77 {
 78     check(0, "back on empty StrBlob");
 79     return data->back();
 80 }
 81 
 82 inline void StrBlob::pop_back()
 83 {
 84     check(0, "pop_back on empty StrBlob");
 85     return data->pop_back();
 86 }
 87 
 88 //当试图访问一个不存在的元素时,StrBlobPtr抛出一个异常
 89 class StrBlobPtr {
 90     friend bool eq(const StrBlobPtr&, const StrBlobPtr&);
 91 public:
 92     StrBlobPtr() : curr(0) { }
 93     StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) { }
 94 
 95     string& deref() const;
 96     StrBlobPtr& incr();      //前缀递增
 97     StrBlobPtr& decr();      //前缀递减
 98 private:
 99     // 若检查成功,check返回一个指向vector的shared_ptr
100     shared_ptr<vector<string>> check(size_t, const string&) const;
101     // 保存一个weak_ptr,意味着底层vector可能会被销毁
102     weak_ptr<vector<string>> wptr;
103     size_t curr;
104 };
105 
106 inline shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const
107 {
108     auto ret = wptr.lock();    //vector还存在吗?
109     if (!ret)
110         throw runtime_error("unbound StrBlobPtr");
111     if (i >= ret->size())
112         throw out_of_range(msg);
113     return ret;               //否则,返回指向vector的shared_ptr
114 }
115 
116 inline string& StrBlobPtr::deref() const
117 {
118     auto p = check(curr, "dereference past end");
119     return (*p)[curr];     //(*p)是对象所指的vector
120 }
121 
122 // 前缀递增:返回递增后的对象的引用
123 inline StrBlobPtr& StrBlobPtr::incr()
124 {
125     // 如果curr已经指向容器的尾后位置,就不递增它
126     check(curr, "increment psat end of StrBlobPtr");
127     ++curr;             //推进当前位置
128     return *this;
129 }
130 
131 // 前缀递减,返回递减后的对象的引用
132 inline StrBlobPtr& StrBlobPtr::decr()
133 {
134     // 如果curr已经为0,递减它就会产生一个非法下标
135     --curr;             //递减当前位置
136     check(-1, "decrement past begin of StrBlobPtr");
137     return *this;
138 }
139 
140 // StrBlob的begin和end成员的定义
141 inline StrBlobPtr StrBlob::begin()
142 {
143     return StrBlobPtr(*this);
144 }
145 
146 inline StrBlobPtr StrBlob::end()
147 {
148     auto ret = StrBlobPtr(*this, data->size());
149     return ret;
150 }
151 
152 // StrBlobPtr的比较操作
153 inline bool eq(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
154 {
155     auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
156     if (l == r)
157         return (!r || lhs.curr == rhs.curr);
158     else
159         return false;
160 }
161 
162 inline bool neq(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
163 {
164     return !eq(lhs, rhs);
165 }
166 #endif
167 //main.cc
168 #include <iostream>
169 #include <fstream>
170 using std::cout;
171 using std::endl;
172 using std::ifstream;
173 
174 #include "my_StrBlob.h"
175 
176 int main(int argc, char **argv)
177 {
178     ifstream in(argv[1]);
179     if (!in) {
180         cout<<"Open input file failed"<<endl;
181         return -1;
182     }
183 
184     StrBlob b;
185     string s;
186     while (getline(in, s))
187         b.push_back(s);
188 
189     for (auto it = b.begin(); neq(it, b.end()); it.incr())
190         cout<<it.deref()<<endl;
191 
192     return 0;
193 }

练习12.21

书中的方式更好一些。将合法性检查与元素获取的返回语句分离开来,代码更清晰易读,当执行到第二条语句时,已确保p是存在的vector,curr是合法的位置,可安全地获取元素并返回。这种清晰的结构也更有利于修改不同的处理逻辑。

而本题中的版本将合法性检查和元素获取及返回合在一条语句中,不易读,也不易修改。

练习12.22

1 StrBlobStr(const StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz){} 

 

 

转载于:https://www.cnblogs.com/wuyinfenghappy/p/7448917.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值