allocator例子

13.39 编写自己的StrVec,包括自己版本的reserve、capacity和resize。

13.40 为StrVec添加一个构造函数,它接受一个initializer_list<string>参数

StrVec.h

#ifndef STRVEC_H
#define STRVEC_H
#include<iostream>
#include<string>
#include<utility>
#include<memory>
using namespace std;
class StrVec
{
public:
    StrVec():elements(nullptr),first_free(nullptr),cap(nullptr){}
    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(size_t n);
    void resize(size_t n,string s=string());

    StrVec(initializer_list<string> il)
    {
        auto newcapacity=il.size();
        auto newdata=alloc.allocate(newcapacity);
        auto dest=newdata;
        auto elem=il.begin();
        while(elem!=il.end())
            alloc.construct(dest++,*elem);
        elements=newdata;
        first_free=cap=dest;
    }
private:
    static allocator<string> alloc;
    string *elements;
    string *first_free;
    string *cap;
    void chk_n_alloc()
    {
        if(size()==capacity()) reallocate();
    }
    pair<string*,string*> alloc_n_copy(const string*,const string*);
    void free();
    void reallocate();
};
#endif // STRVEC_H

StrVec.cpp

#include"StrVec.h"

allocator<string> StrVec::alloc;
StrVec::StrVec(const StrVec &s)
{
    auto newdata=alloc_n_copy(s.begin(),s.end());
    elements=newdata.first;
    first_free=newdata.second;
    cap=newdata.second;
}

StrVec& StrVec::operator=(const StrVec &s)
{
    auto data=alloc_n_copy(s.begin(),s.end());
    free();
    elements=data.first;
    first_free=cap=data.second;
    return *this;
}

StrVec::~StrVec()
{
    free();
}

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_each(&first_free,&elements,[](string *p) { alloc.destroy(p);}); lambda式子
for(auto p=first_free;p!=elements;) alloc.destroy(--p); alloc.deallocate(elements,cap-elements); } } 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++)); elements=newdata; first_free=dest; cap=elements+newcapacity; } void StrVec::reserve(size_t n) { if(capacity()<n) reallocate(); } void StrVec::resize(size_t n,string s) { if(size()<n) push_back(s); else if(size()>n) { for(auto p=elements+n;p!=first_free;) alloc.destroy(p++); first_free=elements+n; } }
原文地址:https://www.cnblogs.com/wuchanming/p/3932643.html