StrBlob.h
#include<string> #include<vector> #include<memory> #iclude<initializer_list> #inlude<stdexcept> #ifndef STRBLOB__H #define STRBLOB__H class StrBlob { public: friend class StrBlobPtr;// so in StrBlobPtr can use StrBlob instance access StrBlob private member typedef std::string::size_type size_type; StrBlob(): data(std::make_shared<std::vector<std::string>>()) {} StrBlob(const std::initializer_list<std::string> &li): data(std::make_shared<std::vector<std::string>>(li)) {} size_type size() const {return data->size();} bool empty() const {return data->empty();} void push_back(const std::string &str) { data->push_back(str);} void pop_back(); std::string& front() const; std::string& back() const; private: std::shared_ptr<std::vector<std::string>> data; void check(const size_type &i, const std::string &msg) const; }; class StrBlobPtr { public: StrBlobPtr(): curr(0) {}; StrBlobPtr(StrBlob &sb, const size_t &sz) : w_ptr(sb.data), curr(sz) {} std::string& deref(); void incr(); private: std::shared_ptr<std::vector<std::string>> check(const std::string &msg) const; std::weak_ptr<std::vector<std::string>> w_ptr; size_t curr; }; #endif
StrBlob.cpp
#include<StrBlob.h> void StrBlob::pop_back() { check(0, "pop_back is out of range"); data->pop_back(); } std::string& StrBlob::front() const { check(0, "front is out of range"); return data->front(); } std::string& StrBlob::back() const { check(0, "back is out of range"); return data->back(); } void StrBlob::check(const std::string& msg) const { if(i>=data->size()) throw std::out_of_range(msg); } std::string& StrBlobPtr::deref() { std::shared_ptr<std::vector<std::string>> ptr = w_ptr.check("deref"); return (*ptr)[curr]; } void StrBlobPtr::incr() { check("increase"); ++curr; } std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(const std::string &msg) const { std::shared_ptr<std::vector<std::string>> ptr = w_ptr.lock(); if(!ptr) throw std::runtime_error("unbound StrBlobPtr"); if(curr >= ptr->size()) throw std::out_of_range(msg); return ptr; }
感觉StrBlobPtr就是强行使用weak_ptr,并没有实际的用途,除非StrBlob对象销毁了,shared_ptr指针data销毁了,weak_ptr指针w_ptr的check操作才会起到作用,但是不明白为什么不直接使用StrBlob对象来访问data,而要StrBlobPtr来访问呢?
ifstream is("map.dat"); string line; StrBlob sb; StrBlobPtr sbp(sb, 0); while(getline(is, line)) { sb.push_back(line); } cout<<sb.front()<<endl; cout<<sb.back()<<endl; //for(size_t i=0; i != sb.size(); ++i) { // 必须要借助sb才知道什么时候结束,除非让报out_of_range的异常 // cout<<sbp.deref()<<endl; // sbp.incr(); //} while(1) { try { cout<<sbp.deref()<<endl; sbp.incr(); } catch(out_of_range e) { cout<<e.what()<<endl; break; } catch(runtime_error e) { cout<<e.what()<<endl; break; } }