编写一个StrVec类
其中涉及到动态内存管理,内存分配,for_each,lambda表达式在类中使用,初始化列表等问题。
#include <bits/stdc++.h>
using namespace std;
class StrVec
{
public:
StrVec():
elements(nullptr),first_free(nullptr),cap(nullptr){}
StrVec(const initializer_list<string> &vs)
{
elements=nullptr;
first_free=nullptr;
cap=nullptr;
for(auto it:vs)
this->Push_back(it);
}
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; }
void Reserve(const size_t&);
void Resize(size_t );//重新分配大小,相对于Size
void Resize(size_t ,const string&);//
private:
static allocator<string> alloc;
void chk_n_alloc()
{
if (Size() == Capacity() )
reallocate();
}
pair<string*,string*> alloc_n_copy(const string*,const string *);
void Free();
void reallocate();
string *elements;
string *first_free;
string *cap;
};
allocator<string> StrVec::alloc;
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)
{
//此处传递到lambda参数应该是*element而不是element,所以应该是destroy(&p)
for_each(elements,first_free,[this](string &p){ alloc.destroy(&p);});
/*
for(auto p=first_free;p!=elements;)
alloc.destroy(--p);
*/
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;
first_free = cap = data.second;
return *this;
}
void StrVec::reallocate()
{
auto newcapacity = Size() ? 2 * Size() : 1;
auto newdata = alloc.allocate(newcapacity);//申请两倍内存
auto dest = newdata;//alloc返回的首指针
auto elem = elements;
for(size_t i=0;i!=Size();++i)
alloc.construct(dest++,move(*elem++));
Free();
elements = newdata;//新的首指针
first_free = dest;
cap = elements + newcapacity;
}
void StrVec::Reserve(const size_t& len)//重新分配大小
{
if(len<=cap-elements)//小于或等于不申请
return ;
//未构造的内存减少
auto newcapacity = len;
auto newdata = alloc.allocate(newcapacity);//申请len倍内存
auto dest = newdata;//alloc返回的首指针
auto elem = elements;
for(size_t i=0;i!=Size();++i)
alloc.construct(dest++,move(*elem++));
Free();
elements = newdata;//新的首指针
first_free = dest;
cap = elements + newcapacity;
}
void StrVec::Resize(size_t n)
{
if(n>Size())//重新分配空间,并初始化构造
{
if(n>cap-elements)//如果比内存空间长度还要大
{
Reserve(n);
}
else
{
string s="";
while(first_free-elements!=n)
{
alloc.construct(first_free++,s);//添加构造
}
}
}
else
{
while(first_free-elements!=n)
{
alloc.destroy(--first_free);//销毁构造
}
}
}
void StrVec::Resize(size_t n,const string &s)
{
if(n == Size())
return;
if(n>Size())//重新分配空间,并初始化构造
{
if(n>cap-elements)//如果比内存空间长度还要大
{
Reserve(n);
for(size_t i=Size();i!=n;++i)
alloc.construct(first_free++,s);
}
}
else
{
while(first_free-elements!=n)
{
alloc.destroy(--first_free);//销毁构造
}
}
}
int main()
{
ios::sync_with_stdio(false);
return 0;
}