C++primer练习12.19-12.22

练习12.19

定义你自己的StrBlobPtr,更新StrBlob类,加入恰当的friend声明及begin、end成员

class StrBlobPtr{
    public:
        StrBlobPtr():curr(0){}
        StrBlobPtr(StrBlob&a,size_t sz):wptr(a.data),curr(sz){}
        string& deref()const;
        StrBlobPtr& incr();
                
    private:
        shared_ptr<vector<string>> check(size_t,const string&)const;
        weak_ptr<vector<string>> wptr;
        size_t curr;
        
};
shared_ptr<vector<string>> StrBlobPtr::check(size_t sz,const string&s)const
{
    auto ret=wptr.lock();
    if(!ret)
    throw runtime_error("unbound StrBlobPtr");
    if(sz>=ret->size())
    throw out_of_range(s);
    return ret;
}
string& StrBlobPtr::deref()const
{
auto p=check(curr,"dereference past end");
return (*p)[curr];    
}

StrBlobPtr& StrBlobPtr::incr()
{
    check(curr,"increment past end of StrBlobPtr");
    ++curr;
    return *this;
}
class StrBlob{
    friend class StrBlobPtr;
    public:
        typedef vector<string>::size_type size_type;
        StrBlob();
        StrBlob(initializer_list<string> il);
        size_type size()const{return data->size();}
        bool empty()const{return data->empty();}
        StrBlobPtr begin(){return StrBlobPtr(*this);}
        StrBlobPtr end()
        {auto ret =StrBlobPtr(*this,data->size());
        return ret;
        }
        void push_back(const string &t){data->push_back(t);}
        void pop_back();
        
        string &front();
        string &back();
        string &front()const;
        string &back()const;
        
    private:
        shared_ptr<vector<string>> data;
        void check(size_type i,const string &msg)const;
};

练习12.20

编写程序,逐行读入一个输入文件,将内容存入一个StrBlob中,用一个StrBlobPtr打印出StrBlob的每一个元素

#include<iostream>
#include"StrBlobPtr.h"
#include"StrBlob.h"
#include"StrBlob.cpp"
#include"StrBlobPtr.cpp" 
#include <fstream>
using namespace std;

int main(int argc, char *argv[])
{
    ifstream in("number.txt");
    StrBlob m_sb;

    string word;
 
    while(getline(in, word))
        m_sb.push_back(word);

  
    StrBlobPtr m_sbp(m_sb, 0);

    for(StrBlobPtr e = m_sb.end();
        m_sbp.re_curr() != e.re_curr();m_sbp.incr())
        cout<<m_sbp.defen()<<endl;

    return 0;
    
    
    
}

注意模板类的多文件编译,必须把成员函数定义也放在头文件,我也不知道为什么,好像STL啥啥的,唉麻了

练习12.21

也可以这样编写StrBlobPtr的deref成员:

std::string & deref()const

{return (*check(curr,“dereference past end”))[curr];}

你认为哪个版本更好?

::个人感觉没必要省一行空间出来,过于浓缩让可读性变差,而且不易于日后修改吧

练习12.22

为了能让StrBlobPtr使用const StrBlob,你觉得应该如何修改?定义一个名为ConstStrBlobPtr的类,使其能指向const StrBlob

class ConstStrBlobPtr {
public:
    
    StrBlobPtr (const StrBlob &a, size_t sz);

  
    const string& defen() const;

  
    const StrBlobPtr& incr();

    size_t re_curr();

private:
   
    shared_ptr<vector<string>> check(size_t sz, const string& msg) const;

   
    weak_ptr<vector<string>> wptr;
   
    size_t curr;
};

 

posted @ 2022-08-08 21:01  yddl  阅读(39)  评论(0编辑  收藏  举报