diff --git a/ch12/ex12_19.h b/ch12/ex12_19.h index 7c470803..43d55aba 100644 --- a/ch12/ex12_19.h +++ b/ch12/ex12_19.h @@ -42,11 +42,22 @@ class StrBlob { check(0, "pop_back on empty StrBlob"); data->pop_back(); } - const std::string& front() { + + 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 std::string& back() const { check(0, "back on empty StrBlob"); return data->back(); } diff --git a/ch12/ex12_22.h b/ch12/ex12_22.h index 57bdcd35..d3c8835d 100644 --- a/ch12/ex12_22.h +++ b/ch12/ex12_22.h @@ -28,35 +28,46 @@ class StrBlob { public: using size_type = vector::size_type; friend class ConstStrBlobPtr; - + ConstStrBlobPtr begin() const; // should add const ConstStrBlobPtr end() const; // should add const - + StrBlob():data(std::make_shared>()) { } StrBlob(std::initializer_list il):data(std::make_shared>(il)) { } - + 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(); } - const std::string& front() { + + 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 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> data; }; @@ -75,7 +86,7 @@ class ConstStrBlobPtr { ++curr; return *this; } - + private: std::shared_ptr> check(size_t i, const string &msg) const { auto ret = wptr.lock(); @@ -84,7 +95,7 @@ class ConstStrBlobPtr { return ret; } std::weak_ptr> wptr; - size_t curr; + size_t curr; }; -#endif \ No newline at end of file +#endif diff --git a/ch13/README.md b/ch13/README.md index 93b69c60..8816802d 100644 --- a/ch13/README.md +++ b/ch13/README.md @@ -93,7 +93,7 @@ The compiler defines a synthesized destructor for any class that does not define When a `StrBlob` object destroyed, the `use_count` of the dynamic object will decrement. It will be freed if no `shared_ptr` to that dynamic object. -When a `StrBlobPter` object is destroyed the object dynamicaly allocated will not be freed. +When a `StrBlobPter` object is destroyed the object dynamically allocated will not be freed. ## [Exercise 13.11](ex13_11.h) @@ -169,16 +169,16 @@ QueryResult& operator=(const QueryResult) = delete; Check 13.22. ## Exercise 13.24: ->What would happen if the version of HasPtr in this section didn’t define a destructor? What if HasPtr didn’t define the copy constructor? +>What would happen if the version of `HasPtr` in this section didn’t define a destructor? What if `HasPtr` didn’t define the copy constructor? If `HasPtr` didn't define a destructor, memory leak will happened. If `HasPtr` didn't define the copy constructor, when assignment happened, just points copied, the string witch `ps` points haven't been copied. ## Exercise 13.25: ->Assume we want to define a version of StrBlob that acts like a value. Also assume that we want to continue to use a shared_ptr so that our StrBlobPtr class can still use a weak_ptr to the vector. Your revised class will need a copy constructor and copy-assignment operator but will not need a destructor. Explain what the copy constructor and copyassignment operators must do. Explain why the class does not need a destructor. +>Assume we want to define a version of `StrBlob` that acts like a value. Also assume that we want to continue to use a shared_ptr so that our `StrBlobPtr` class can still use a weak_ptr to the vector. Your revised class will need a copy constructor and copy-assignment operator but will not need a destructor. Explain what the copy constructor and copy-assignment operators must do. Explain why the class does not need a destructor. -Copy constructor and copy-assignment operator should dynamicly allocate memory for its own , rather than share the object with the right hand operand. +Copy constructor and copy-assignment operator should dynamically allocate memory for its own , rather than share the object with the right hand operand. -`StrBlob` is using smart pointers which can be managed with synthesized destructor, If an object of `StrBlob` is out of scope, the destructor for std::shared_ptr will be called automaticaly to free the memory dynamically allocated when the `use_count` goes to 0. +`StrBlob` is using smart pointers which can be managed with synthesized destructor, If an object of `StrBlob` is out of scope, the destructor for std::shared_ptr will be called automatically to free the memory dynamically allocated when the `use_count` goes to 0. ## Exercise 13.26 [hpp](ex13_26.h) | [cpp](ex13_26.cpp) diff --git a/ch13/ex13_26.h b/ch13/ex13_26.h index 07734d3d..70b3f4ef 100644 --- a/ch13/ex13_26.h +++ b/ch13/ex13_26.h @@ -5,7 +5,7 @@ // Created by pezy on 1/19/15. // Copyright (c) 2014 pezy. All rights reserved. // -// Write your own version of the StrBlob class described in the previous exercise. +// Write your own version of the StrBlob class described in the previous exercise. // // @See ex12_22 and ex13_25 @@ -26,40 +26,51 @@ class StrBlob { public: using size_type = vector::size_type; friend class ConstStrBlobPtr; - + ConstStrBlobPtr begin() const; ConstStrBlobPtr end() const; - + StrBlob():data(std::make_shared>()) { } StrBlob(std::initializer_list il):data(std::make_shared>(il)) { } - + // copy constructor StrBlob(const StrBlob& sb) : data(std::make_shared>(*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(); } - const std::string& front() { + + std::string& front() { check(0, "front on empty StrBlob"); return data->front(); } - const std::string& back() { + + 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> data; }; @@ -78,7 +89,7 @@ class ConstStrBlobPtr { ++curr; return *this; } - + private: std::shared_ptr> check(size_t i, const string &msg) const { auto ret = wptr.lock(); @@ -87,7 +98,7 @@ class ConstStrBlobPtr { return ret; } std::weak_ptr> wptr; - size_t curr; + size_t curr; }; #endif