不使用模板,建立一个用于string的可以自己分配内存的类
StrVec类的设计
使用allocator获得原始内存,并使用allocator的construct成员在内存中创建对象,删除元素使用destroy
使用三个指针依次指向首元素、尾元素和内存末尾的位置,使用alloc静态成员分配StrVec使用的内存,建立四个工具函数,alloc_n_copy会分配内存,并拷贝一个指定范围中的元素,free销毁构造元素并释放内存,chk_n_alloc保证StrVec至少有容纳一个新元素的空间,如果没有空间添加新元素,chk_n_alloc会调用reallocate来分配更多内存,reallocate在内存用完时为StrVec分配新内存
StrVec定义
class StrVec
{
public:
StrVec():elements(nullptr), first_free(nullptr), cap(nullptr){}
StrVec(const StrVec&);
StrVec& operator=(const StrVec&);
~StrVec();
void push_back(const std::string&);
size_t size() const{return first_free - elements};
size_t capacity() const {return cap - elements};
std::string *begin() const {return elements};
std::string *end() const {return firdt_free};
private:
static std::allocator<std::string> alloc;
void chk_n_alloc()
{
if (size() == capacity())
reallocate();
}
std::pair<std::string*, std::string*> alloc_n_copy(const std::string*, const std string*);
void free();
void reallocator();
std::string *elements;
std::string *first_free;
std::string *cap;
};使用construct
利用construct创建新对象
void StrVec::push_back(const string &s)
{
chk_n_alloc();
alloc.construct(first_free++,s);
}alloc_n_copy成员
当进行拷贝时,需要分配新的内存资源,此函数是在返回值中进行拷贝工作的
pair<string* ,string*> StrVec::alloc_n_alloc(const string *b, const string *e)
{
auto data = alloc.allocate(e - b);
return {data, uninitialized_copy(b, e, data)};
}free成员
void StrVec::free()
{
if(elements)
{
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 = newdat.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;
}reallocate成员
void StrVec::reallocate()
{
auto newcapacity = size() ?2 * size() : 1;
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for(size_t i = 0; i != size(); ++i)
{
alloc.construct(dest++, std::move(*elem++));
}
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
京公网安备 11010502036488号