练习12.1:在此代码的结尾,b1和b2各包含多少个元素?
StrBlob b1;
{
StrBlob b2 = {"a", "an", "the"};
b1 = b2;
b2.push_back("about");
}
答:b1包含4个元素 b2由于新加了一个元素包含4个元素。因为里面用了共享内存
练习12.2:编写你自己的StrBlob类,包含const版本的front和back。
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <stack>
#include <string>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <memory>
#include <initializer_list>
using namespace std;
class StrBlob {
public:
typedef vector<string>::size_type s_type;
StrBlob();
StrBlob(initializer_list<string> li); //如果不是列表呢
s_type size() const{
return data->size();
}
bool empty() const {
return data->empty();
}
//删除和添加元素
void push_back(const string t){
data->push_back(t);
}
void pop_back();
string& front();
string& back();
void pop_back() const;
string& front() const;
string& back() const;
private:
shared_ptr<std::vector<std::string>> data;
void check(s_type i, const string &msg) const;
};
StrBlob::StrBlob() :data(make_shared<vector<string>>()){ }
StrBlob::StrBlob(initializer_list<string> li) : data(make_shared<vector<string>>(li)){ }
string& StrBlob::front(){
check(0, "front on empty StrBlob");
return data->front();
}
string& StrBlob::back(){
check(0, "pop_back on empty StrBlob");
return data->back();
}
void StrBlob::check(s_type i, const string &msg) const{
if (i >= data->size())
throw out_of_range(msg);
}
string& StrBlob::front() const{
check(0, "front on empty StrBlob");
return data->front();
}
string& StrBlob::back() const{
check(0, "pop_back on empty StrBlob");
return data->back();
}
int _tmain(int argc, _TCHAR* argv[])
{
const StrBlob b = { "aaa", "bbb", "ccc" };
int a = b.size();
string c = b.back();
return 0;
}
练习12.3:StrBlob 需要const 版本的push_back和pop_back吗?如果需要添加进去。否则,解释为什么不需要。
答 :不需要 因为这两个函数都需要改变指针指向的对象,如果设置为const的成员函数,将会把this指针隐式的转换为const StrBlob const *this //伪代码
练习12.4:在我们的check函数中,没有坚持i大于0。为什么可以忽略这个检查?
答:因为传入数据类型为size_type时大于等于0的所以没有必要检查。
练习12.5:我们未编写接受一个initializer_list explicit参数的构造函数。讨论这个策略的优点和缺点。