c++ 动态内存
StrBlob.h
#include<string>
#include<vector>
#include<memory>
#iclude<initializer_list>
#inlude<stdexcept>
#ifndef STRBLOB__H
#define STRBLOB__H
class StrBlob {
public:
friend class StrBlobPtr;// so in StrBlobPtr can use StrBlob instance access StrBlob private member
typedef std::string::size_type size_type;
StrBlob(): data(std::make_shared<std::vector<std::string>>()) {}
StrBlob(const std::initializer_list<std::string> &li): data(std::make_shared<std::vector<std::string>>(li)) {}
size_type size() const {return data->size();}
bool empty() const {return data->empty();}
void push_back(const std::string &str) { data->push_back(str);}
void pop_back();
std::string& front() const;
std::string& back() const;
private:
std::shared_ptr<std::vector<std::string>> data;
void check(const size_type &i, const std::string &msg) const;
};
class StrBlobPtr {
public:
StrBlobPtr(): curr(0) {};
StrBlobPtr(StrBlob &sb, const size_t &sz) : w_ptr(sb.data), curr(sz) {}
std::string& deref();
void incr();
private:
std::shared_ptr<std::vector<std::string>> check(const std::string &msg) const;
std::weak_ptr<std::vector<std::string>> w_ptr;
size_t curr;
};
#endif
StrBlob.cpp
#include<StrBlob.h>
void StrBlob::pop_back() {
check(0, "pop_back is out of range");
data->pop_back();
}
std::string& StrBlob::front() const {
check(0, "front is out of range");
return data->front();
}
std::string& StrBlob::back() const {
check(0, "back is out of range");
return data->back();
}
void StrBlob::check(const std::string& msg) const {
if(i>=data->size())
throw std::out_of_range(msg);
}
std::string& StrBlobPtr::deref() {
std::shared_ptr<std::vector<std::string>> ptr = w_ptr.check("deref");
return (*ptr)[curr];
}
void StrBlobPtr::incr() {
check("increase");
++curr;
}
std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(const std::string &msg) const {
std::shared_ptr<std::vector<std::string>> ptr = w_ptr.lock();
if(!ptr)
throw std::runtime_error("unbound StrBlobPtr");
if(curr >= ptr->size())
throw std::out_of_range(msg);
return ptr;
}
感觉StrBlobPtr就是强行使用weak_ptr,并没有实际的用途,除非StrBlob对象销毁了,shared_ptr指针data销毁了,weak_ptr指针w_ptr的check操作才会起到作用,但是不明白为什么不直接使用StrBlob对象来访问data,而要StrBlobPtr来访问呢?
ifstream is("map.dat");
string line;
StrBlob sb;
StrBlobPtr sbp(sb, 0);
while(getline(is, line)) {
sb.push_back(line);
}
cout<<sb.front()<<endl;
cout<<sb.back()<<endl;
//for(size_t i=0; i != sb.size(); ++i) { // 必须要借助sb才知道什么时候结束,除非让报out_of_range的异常
// cout<<sbp.deref()<<endl;
// sbp.incr();
//}
while(1) {
try {
cout<<sbp.deref()<<endl;
sbp.incr();
} catch(out_of_range e) {
cout<<e.what()<<endl;
break;
} catch(runtime_error e) {
cout<<e.what()<<endl;
break;
}
}