欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

StrBlobPtr类——weak_ptr访问vector元素

程序员文章站 2022-03-23 14:05:31
...
#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!\n");
    data->pop_back();
}

string& StrBlob::front()
{
    check(0, "此StrBlob对象指向一个空vector!\n");
    return data->front();
}

string& StrBlob::back()
{
    check(0, "此StrBlob对象指向一个空vector!\n");
    return data->back();
}

const string& StrBlob::front() const
{
    check(0, "此StrBlob对象指向一个空vector!\n");
    cout << "调用对象为const StrBlob!\n";
    return data->front();
}

const string& StrBlob::back() const
{
    check(0, "此StrBlob对象指向一个空vector!\n");
    cout << "调用对象为const StrBlob!\n";
    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>对象不存在!\n");
    if (i >= ret->size())
        throw out_of_range(msg);
    return ret;
}

string& StrBlobPtr::deref() const
{
    auto p = check(curr, "当前下标不合法!\n");
    return (*p)[curr]; 
}

StrBlobPtr& StrBlobPtr::incr()
{
    check(curr, "不能继续递增了\n");
    ++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; 
}