#include <iostream> #include <memory> #include <string> #include <initializer_list> #include <vector> #include <stdexcept> using namespace std; class StrBlobPtr; class StrBlob { friend class StrBlobPtr; public: using size_type = vector<string>::size_type; StrBlob(); StrBlob(initializer_list<string> il); size_type size() const { return data->size(); } bool empty() const { return data->empty(); } void push_back(const string &s); void pop_back(); //返回string的引用,是因为调用点会使用该string //如b.front() = "first"; string& front(); string& back(); //只有const StrBlob对象才会调用以下函数 const string& front() const; const string& back() const; StrBlobPtr begin(); StrBlobPtr end(); private: shared_ptr<vector<string>> data; void check(size_type i, const string &msg) const; }; StrBlob::StrBlob(): data(make_shared<vector<string>>()) { } StrBlob::StrBlob(initializer_list<string> il): data(make_shared<vector<string>>(il)) { } void StrBlob::check(size_type i, const string &msg) const { if (i >= data->size()) throw out_of_range(msg); } void StrBlob::push_back(const string &s) { data->push_back(s); } void StrBlob::pop_back() { check(0, "此StrBlob对象指向一个空vector! "); data->pop_back(); } string& StrBlob::front() { check(0, "此StrBlob对象指向一个空vector! "); return data->front(); } string& StrBlob::back() { check(0, "此StrBlob对象指向一个空vector! "); return data->back(); } const string& StrBlob::front() const { check(0, "此StrBlob对象指向一个空vector! "); cout << "调用对象为const StrBlob! "; return data->front(); } const string& StrBlob::back() const { check(0, "此StrBlob对象指向一个空vector! "); cout << "调用对象为const StrBlob! "; return data->back(); } class StrBlobPtr { public: StrBlobPtr(): curr(0) {} StrBlobPtr(StrBlob &b, size_t sz = 0): wptr(b.data), curr(sz) {} string& deref() const; StrBlobPtr& incr(); private: weak_ptr<vector<string>> wptr; size_t curr; shared_ptr<vector<string>> check(size_t i, const string &msg) const; }; shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const { auto ret = wptr.lock(); if (!ret) throw runtime_error("要访问的vector<string>对象不存在! "); if (i >= ret->size()) throw out_of_range(msg); return ret; } string& StrBlobPtr::deref() const { auto p = check(curr, "当前下标不合法! "); return (*p)[curr]; } StrBlobPtr& StrBlobPtr::incr() { check(curr, "不能继续递增了 "); ++curr; return *this; } StrBlobPtr StrBlob::begin() { return StrBlobPtr(*this); } StrBlobPtr StrBlob::end() { return StrBlobPtr(*this, data->size()); } int main() { StrBlob b1{"mon", "tue", "wed", "thu", "fri"}; StrBlobPtr p(b1, 3); cout << p.deref() << endl; //访问p当前指向的元素 cout << p.incr().deref() << endl; //先递增p,再访问元素 p = b1.begin(); cout << p.deref() << endl; return 0; }