习题12-11
因为p.get()返回一个内置指针,实际上shared_ptr<int>(p.get())创建了一个新的shared_ptr<int>,引用计数为1;这里为什么不是直接在原来的p的引用计数直接增加为2,是因为按照书中P402来看,实际上是因为引用计数的增加是建立在两个shared_ptr之间,而本题实际上是内置指针与shared_ptr之间;
习题12-12
a)和d)合法,b)和c)不合法,不能进行内置指针到智能指针的隐式转换,但是显示转换是合法的;
习题12-13
不能delete,sp与p指向同一内存,当delete p之后,此处内存被释放,之后sp自动释放时,会二次释放内存,产生错误;
习题12-14
不太懂这一块connection的原理,这里讲的知识点就在于用删除器,对智能指针进行释放操作;
习题12-15
shared_ptr<connection> p(&c,lambda[](connection *p){disconnect(*p);});
习题12-16
#include <iostream>
#include <memory>
using namespace std;
void main()
{
unique_ptr<int> p(new int(42));
unique_ptr<int> q(p);
}
报错error C2280: “std::unique_ptr<int,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)”: 尝试引用已删除的函数
习题12-17
(a)不合法,不能讲int型转化为new int*;
(b)不合法,会通过编译,但无法释放内存,导致错误;
(c)不合法,会导致p2成为空悬指针;
(d)不合法,但无法释放内存;
(e)合法
(d)不合法,p2和p5指向同一对象,unique_ptr会释放两次内存;
习题12-18
release是为了让unique_ptr取得唯一的控制权,而shard_ptr是多对一,使用了release也不能保证唯一的控制权,没有必要;
习题12-19
抄一遍。。
class StrBlobPtr;
class StrBlob
{
public:
using size_type = vector<string>::size_type;
friend class StrBlobPtr;
StrBlobPtr begin();
StrBlobPtr end();
StrBlob() : data(std::make_shared<vector<string>>()) {}
StrBlob(std::initializer_list<string> il) : data(std::make_shared<vector<string>>(il)) {}
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const string& s) { data->push_back(s); }
void pop_back()
{
check(0, "pop_back on empty StrBlob");
data->pop_back();
}
std::string& front()
{
check(0, "front on empty StrBlob");
return data->front();
}
std::string& back()
{
check(0, "back on empty StrBlob");
return data->back();
}
const std::string& front() const
{
check(0, "front on empty StrBlob");
return data->front();
}
const std::string& back() const
{
check(0, "back on empty StrBlob");
return data->back();
}
private:
void check(size_type i, const string& msg) const
{
if (i >= data->size())
throw std::out_of_range(msg);
}
private:
std::shared_ptr<vector<string>> data;
};
class StrBlobPtr
{
public:
StrBlobPtr() :curr(0) {}
StrBlobPtr(StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz) {}
bool operator!=(const StrBlobPtr& p) { return p.curr != curr; }
string& deref() const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
StrBlobPtr& incr()
{
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
private:
std::shared_ptr<vector<string>> check(size_t i, const string &msg) const
{
auto ret = wptr.lock();
if (!ret) throw std::runtime_error("unbound StrBlobPtr");
if (i >= ret->size()) throw std::out_of_range(msg);
return ret;
}
std::weak_ptr<vector<string>> wptr;
size_t curr;
};
StrBlobPtr StrBlob::begin()
{
return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
return StrBlobPtr(*this, data->size());
}
习题12-20
#include <iostream>
#include <fstream>
using namespace std;
//加入19题定义的类
int main()
{
ifstream ifs("data.txt");
StrBlob sb;
string s;
while (getline(ifs, s))
sb.push_back(s);
for (StrBlobPtr sbp = sb.begin(); sbp != sb.end(); sbp.incr())
cout << sbp.deref() << endl;
return 0;
}