Hi i am reading C++ primer 5th addition and have some doubts in the section of weak_ptr. It is written that
By using a weak_ptr, we don’t affect the lifetime of the vector to which a given StrBlob points. However, we can prevent the user from attempting to access a vector that no longer exists.
Then they have given the following code as an example:
#include<iostream>
#include<string>
#include<vector>
#include<memory>
#include<initializer_list>
using namespace std;
class StrBlobPtr;
class StrBlob {
friend class StrBlobPtr;
public:
typedef std::vector<std::string>::size_type size_type;
StrBlob():data(std::make_shared<std::vector<std::string>>()){
}
StrBlob(std::initializer_list<std::string> il):data(make_shared<vector<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);
}
std::string& front(){
check(0,"front on empty StrBlob");
return data->front();
}
std::string& front() const{
check(0,"front on const empty StrBlob");
return data->front();
}
std::string& back(){
check(0,"back on empty StrBlob");
return data->back();
}
std::string& back() const {
check(0,"back on const empty StrBlob");
return data->back();
}
void pop_back(){
check(0,"pop_back on empty StrBlob");
data->pop_back();
}
private:
std::shared_ptr<std::vector<std::string>> data;
void check(size_type i, const std::string &msg) const{
if(i >= data->size()){
throw out_of_range(msg);
}
}
StrBlobPtr begin();
StrBlobPtr end();
};
class StrBlobPtr {
public:
typedef std::vector<std::string>::size_type size_type;
StrBlobPtr():curr(0){
}
StrBlobPtr(StrBlob &a, size_type sz = 0):wptr(a.data), curr(sz){
}
std::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;
}
std::shared_ptr<std::vector<std::string>> check(std::size_t i, const std::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;
}
private:
std::weak_ptr<std::vector<std::string>> wptr;
size_type curr;
};
StrBlobPtr StrBlob::begin() {
return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end() {
auto ret = StrBlobPtr(*this, data->size());
}
int main(){
return 0;
}
My questions are as follows:
- How can we prevent the user from attempting to access a vector that no longer exists? I can't come up with a use case,how can we use the above quoted statement in this example?
- How does this example shows/verifies that we can prevent the user from attempting to access a vector that no longer exists? *If this example does not shows what they have written then why is this example there in the book?*Note that i have written if.