直接上代码
// StrBlob.h
#include<iostream>
#include<string>
#include<vector>
#include<memory>
#include<algorithm>
#include<stdexcept>
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();
void print(){
std::for_each(data->begin(),data->end(), [](auto i){ std::cout << i << " ";});
std::cout<< std::endl;
}
StrBlobPtr begin();
StrBlobPtr end();
private:
std::shared_ptr<std::vector<std::string>> data;
// 如果 data[i] 不合法抛出异常
void cheak(size_type i, const std::string &msg) const;
};
class StrBlobPtr
{
public:
StrBlobPtr():curr(0){ }
StrBlobPtr(StrBlob &a, size_t sz=0):
wptr(a.data), curr(sz) { }
std::string &operator*() const ;
StrBlobPtr &operator++(); // 前置递增
private:
std::shared_ptr<std::vector<std::string>>
cheak(std::size_t,const std::string &) const
std::weak_ptr<std::vector<std::string>> wptr;
std::size_t curr; // 在数组中的位置。
};
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::cheak(size_type i, const std::string &msg) const
{
if(i >= data->size()){
throw std::out_of_range(msg);
}
}
std::string &StrBlob::front()
{
cheak(0, "front on empty StrBlob");
return data->front();
}
std::string &StrBlob::back()
{
cheak(0, "front on empty StrBlob");
return data->back();
}
void StrBlob::pop_back()
{
cheak(0, "front on empty StrBlob");
return data->pop_back();
}
std::shared_ptr<std::vector<std::string>>
StrBlobPtr::cheak(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::operator*() const
{
auto p = cheak(curr, "deference past end");
return (*p)[curr];
}
StrBlobPtr & StrBlobPtr::operator++() // 前置递增
{
cheak(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr StrBlob::begin(){ return StrBlobPtr(*this);}
StrBlobPtr StrBlob::end()
{
auto ret = StrBlobPtr(*this, data->size());
return ret;
}
测试:
#include<iostream>
#include"StrBlob.h"
int main(){
StrBlob s1;
{
StrBlob s2= {"a", "an", "the"};
s1 = s2;
s2.push_back("about");
}
// s1.print();
auto iter = s1.begin();
try{
while(true){
std::cout << *iter<< " ";
++iter;
}
}
catch(std::out_of_range err)
{std::cout <<std::endl<< err.what() << std::endl;}
return 0 ;
}
// a an the about
// deference past end