1. 程式人生 > >StrBlobPtr類——weak_ptr訪問vector元素

StrBlobPtr類——weak_ptr訪問vector元素

lob 使用 mem row 元素 bsp mon runt runtime

#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; 
}

StrBlobPtr類——weak_ptr訪問vector元素