C++Primer 5版12.1.6節練習

22692 ワード

練習12.19:あなたのバージョンを定義するStrBlobPtrは、StrBlobクラスを更新し、適切なfriendステートメントとbeginとendメンバーを追加します.
/*
*  12.19 
*2016/1/22
*    :
  12.19:        StrBlobPtr,  StrBlob ,     friend   

begin end  。 
*  :http://blog.csdn.net/sunhero2010/article/details/49882993 
*  :Nick Feng
*  :[email protected] 
*/ 

/*
*  12.7 
*2015/11/2
*    :
  12.7:     ,    shared_ptr       。
  12.6:    ,         int vector。  vector        

,          ,        vector   。  vector
        ,      。        delete vector。 
*  :     fun(),fun2(),fun3()             , 12.7    

    ,               
*  :Nick Feng
*  :[email protected] 
*/ 
#include 
#include 
#include 
#include 
#include 
using namespace std;

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();
    const std::string& front();
    const std::string& back();

    StrBlobPtr begin();
    StrBlobPtr end();
private:
    std::shared_ptr<std::vector<std::string>> data;
    void check(size_type i, const std::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);
}

const string& StrBlob::front()
{
    check(0,"front on empty StrBlob");
    return data->front();
}

const string& StrBlob::back()
{
    check(0,"back on empty StrBlob");
    return data->back();    
}

void StrBlob::pop_back()
{
    check(0,"pop_back on empty StrBlob");
    data->pop_back();
}



class StrBlobPtr{
    friend bool eq(const StrBlobPtr&, const StrBlobPtr&); 
    public:
        StrBlobPtr() : curr(0) { }
        StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr

(sz) { }
        std::string& deref() const;
        StrBlobPtr& incr(); //     
    private:
        //     ,check      vector shared_ptr 
        std::shared_ptr<std::vector<std::string>> check(std::size_t, 

const std::string&) const;
        //    weak_ptr,     vector      
        std::weak_ptr<std::vector<std::string>> wptr;
        std::size_t curr;//          
};

std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(std::size_t i, 

const std::string &msg) const
{
    auto ret = wptr.lock(); //vector     ? 
    if(!ret)
        throw std::runtime_error("unbound StrBlobPtr");
    if(i >= ret->size())
        throw std::out_of_range(msg);
    return ret; //  ,    vector shared_ptr 
}

std::string&  StrBlobPtr::deref() const
{
    auto p = check(curr,"dereference past end");
    return (*p)[curr];  //(*p)       vector 
}

//    :            
StrBlobPtr& StrBlobPtr::incr()
{
    //  curr            ,       
    check(curr,"increment past end of StrBlobPtr");
    ++curr;   //       
    return *this;
}


inline StrBlobPtr StrBlob::begin()  
{  
    return StrBlobPtr(*this);  
}  

inline StrBlobPtr StrBlob::end()  
{  
    auto ret = StrBlobPtr(*this, data->size());  
    return ret;  
}  

/*     */
inline bool eq(const StrBlobPtr &lhs, const StrBlobPtr &rhs)  
{  
    auto l = lhs.wptr.lock(), r = rhs.wptr.lock();  
    if (l == r)  
        return (!r || lhs.curr == rhs.curr);  
    else  
        return false;  
}  

/*      */ 
inline bool neq(const StrBlobPtr &lhs, const StrBlobPtr &rhs)  
{  
    return !eq(lhs, rhs);  
}  

int main()
{
StrBlob b1;  
    {  
        StrBlob b2 = {"a", "an", "the"};  
        b1 = b2;  
        b2.push_back("about");  
        cout<cout<cout<" "<for (auto it = b1.begin(); neq(it, b1.end()); it.incr())  
        cout<return 0;
}  
練習12.20:プログラムを作成し、入力ファイルを1行ずつ読み込み、StrBlobに内容を保存し、StrBlobPtrでStrBlobの各要素をプリントアウトします.
/*
*  12.20 
*2016/1/22
*    :
  12.20:    ,          ,       StrBlob ,   

StrBlobPtr   StrBlob      。 
*  :http://blog.csdn.net/sunhero2010/article/details/49882993 
*  :Nick Feng
*  :[email protected] 
*/ 

/*
*  12.7 
*2015/11/2
*    :
  12.7:     ,    shared_ptr       。
  12.6:    ,         int vector。  vector        

,          ,        vector   。  vector
        ,      。        delete vector。 
*  :     fun(),fun2(),fun3()             , 12.7    

    ,               
*  :Nick Feng
*  :[email protected] 
*/ 
#include 
#include 
#include 
#include 
#include 
using namespace std;

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();
    const std::string& front();
    const std::string& back();

    StrBlobPtr begin();
    StrBlobPtr end();
private:
    std::shared_ptr<std::vector<std::string>> data;
    void check(size_type i, const std::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);
}

const string& StrBlob::front()
{
    check(0,"front on empty StrBlob");
    return data->front();
}

const string& StrBlob::back()
{
    check(0,"back on empty StrBlob");
    return data->back();    
}

void StrBlob::pop_back()
{
    check(0,"pop_back on empty StrBlob");
    data->pop_back();
}



class StrBlobPtr{
    friend bool eq(const StrBlobPtr&, const StrBlobPtr&); 
    public:
        StrBlobPtr() : curr(0) { }
        StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr

(sz) { }
        std::string& deref() const;
        StrBlobPtr& incr(); //     
    private:
        //     ,check      vector shared_ptr 
        std::shared_ptr<std::vector<std::string>> check(std::size_t, 

const std::string&) const;
        //    weak_ptr,     vector      
        std::weak_ptr<std::vector<std::string>> wptr;
        std::size_t curr;//          
};

std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(std::size_t i, 

const std::string &msg) const
{
    auto ret = wptr.lock(); //vector     ? 
    if(!ret)
        throw std::runtime_error("unbound StrBlobPtr");
    if(i >= ret->size())
        throw std::out_of_range(msg);
    return ret; //  ,    vector shared_ptr 
}

std::string&  StrBlobPtr::deref() const
{
    auto p = check(curr,"dereference past end");
    return (*p)[curr];  //(*p)       vector 
}

//    :            
StrBlobPtr& StrBlobPtr::incr()
{
    //  curr            ,       
    check(curr,"increment past end of StrBlobPtr");
    ++curr;   //       
    return *this;
}


inline StrBlobPtr StrBlob::begin()  
{  
    return StrBlobPtr(*this);  
}  

inline StrBlobPtr StrBlob::end()  
{  
    auto ret = StrBlobPtr(*this, data->size());  
    return ret;  
}  

/*     */
inline bool eq(const StrBlobPtr &lhs, const StrBlobPtr &rhs)  
{  
    auto l = lhs.wptr.lock(), r = rhs.wptr.lock();  
    if (l == r)  
        return (!r || lhs.curr == rhs.curr);  
    else  
        return false;  
}  

/*      */ 
inline bool neq(const StrBlobPtr &lhs, const StrBlobPtr &rhs)  
{  
    return !eq(lhs, rhs);  
}  

int main()
{
ifstream in("test.txt");  
    if (!in) {  
        cout<<"Open input file failed"<return -1;  
    }  

    StrBlob b;  
    string s;  
    while (getline(in, s))  
        b.push_back(s);  

    for (auto it = b.begin(); neq(it, b.end()); it.incr())  
        cout<return 0;
}  
練習12.21:StrBlobPtrのderefメンバーをこのように作成することもできます.
std:string & deref() const
{ return (*check(curr,"dereference past end"))[curr];}
どのバージョンがいいと思いますか?なぜですか
答書のバージョンはもっと良くて、分けて書いて、分かりやすくて分かります.参照http://blog.csdn.net/sunhero2010/article/details/49882993
練習12.22:StrBlobPtrをconst StrBlobを使えるようにするためには、どうやって修正すればいいと思いますか?ConsStrBloStrというクラスを定義して、const StrBlobを指すことができる.
StrBlobPtrの構造関数を修正すればいいです.
StrBlobStr(const StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz){} 
参考:http://blog.csdn.net/chxw098/article/details/39035885