今天,主要是学习了13.5.这一节主要是帮助理解vector的构造方式,尤其注意allocator的使用。下面是代码:
class StrVec{
public:
StrVec():
elements(nullptr),first_free(nullptr),cap(nullptr){ }
StrVec(initializer_list<string> sl)
{
for(auto i:sl)
push_back(i);
}
StrVec(const StrVec&);
StrVec &operator=(const StrVec&);
~StrVec();
void push_back(const string &);
size_t size() const{return first_free-elements;}
size_t capacity() const{return cap-elements;}
string* begin() const{return elements;}
string* end() const{return first_free;}
private:
allocator<string> alloc;
void chk_n_alloc(){
if(size()==capacity())
reallocate();
}
pair<string *,string *> alloc_n_copy(const string *,const string *);
void free();
void myfree();
void reallocate();
string* elements;
string* first_free;
string* cap;
};
void StrVec::push_back(const string& s)
{
chk_n_alloc();
alloc.construct(first_free++,s);
}
pair<string *,string *> StrVec::alloc_n_copy(const string *b,const string *e)
{
auto data=alloc.allocate(e-b);
return {data,uninitialized_copy(b,e,data)};
}
void StrVec::free()
{
if(elements){
for(auto p=first_free;p!=elements;)
alloc.destroy(--p);
alloc.deallocate(elements,cap-elements);
}
}
void StrVec::myfree()
{
if(elements)
{
for_each(elements,first_free,[this](string &rhs){alloc.destroy(&rhs);});
alloc.deallocate(elements,cap-elements);
}
}
StrVec::StrVec(const StrVec &s)
{
auto newdata=alloc_n_copy(s.begin(),s.end());
elements=newdata.first;
first_free=cap=newdata.second;
}
StrVec::~StrVec()
{
free();
}
StrVec& StrVec::operator=(const StrVec &rhs)
{
auto data=alloc_n_copy(rhs.begin(),rhs.end());
free();
elements=data.first;
cap=first_free=data.second;
return *this;
}
void StrVec::reallocate()
{
auto newcapacity=size()?2*size():1;
auto newdata=alloc.allocate(newcapacity);
auto dest=newdata;
auto elem=elements;
for(auto i=0;i!=size();++i)
alloc.construct(dest++,std::move(*elem++));
free();
elements=newdata;
first_free=dest;
cap=elements+newcapacity;
}