C++Primer 5版12.1.6節練習
22692 ワード
練習12.19:あなたのバージョンを定義するStrBlobPtrは、StrBlobクラスを更新し、適切なfriendステートメントとbeginとendメンバーを追加します.
答書のバージョンはもっと良くて、分けて書いて、分かりやすくて分かります.参照http://blog.csdn.net/sunhero2010/article/details/49882993
練習12.22:StrBlobPtrをconst StrBlobを使えるようにするためには、どうやって修正すればいいと思いますか?ConsStrBloStrというクラスを定義して、const StrBlobを指すことができる.
StrBlobPtrの構造関数を修正すればいいです.
/*
* 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