13.23 有一定差异,我使用if判断是否自我拷贝 本节使用先拷贝右侧对象的方式来使自我拷贝正常运行
13.24 如果没有定义析构函数,肯定会发生内存泄露 如果没有定义拷贝构造函数,当使用了拷贝构造函数时,删除一个对象会使和其他对象共用的内存被释放,其他对象则出现错误
13.25 拷贝构造和拷贝赋值必须新建内存,而不是和右侧共用内存
当shared_ptr计时器为0时,会自动的释放,所以不需要析构函数
13.26 @pezy
https://github.com/PYPARA/Cpp-Primer/blob/master/ch13/ex13_26.h
#include <vector> #include <string> #include <initializer_list> #include <memory> #include <exception> using std::vector; using std::string; class ConstStrBlobPtr; class StrBlob { public: using size_type = vector<string>::size_type; friend class ConstStrBlobPtr; ConstStrBlobPtr begin() const; ConstStrBlobPtr end() const; StrBlob():data(std::make_shared<vector<string>>()) { } StrBlob(std::initializer_list<string> il):data(std::make_shared<vector<string>>(il)) { } // copy constructor StrBlob(const StrBlob& sb) : data(std::make_shared<vector<string>>(*sb.data)) { } // copyassignment operators StrBlob& operator=(const StrBlob& sb); size_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() { 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 ConstStrBlobPtr { public: ConstStrBlobPtr():curr(0) { } ConstStrBlobPtr(const StrBlob &a, size_t sz = 0):wptr(a.data), curr(sz) { } // should add const bool operator!=(ConstStrBlobPtr& p) { return p.curr != curr; } const string& deref() const { // return value should add const auto p = check(curr, "dereference past end"); return (*p)[curr]; } ConstStrBlobPtr& 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; }; ConstStrBlobPtr StrBlob::begin() const // should add const { return ConstStrBlobPtr(*this); } ConstStrBlobPtr StrBlob::end() const // should add const { return ConstStrBlobPtr(*this, data->size()); } StrBlob& StrBlob::operator=(const StrBlob& sb) { data = std::make_shared<vector<string>>(*sb.data); return *this; } int main() { return 0; }