• 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; } }
  • 相关阅读:
    Android 使用EventBus进行Fragment和Activity通信
    Android 实现对多个EditText的监听
    Retrofit2.0动态url遇到的坑
    Android 轻松实现语音朗读
    Android 7.0 因为file://引起的FileUriExposedException异常
    Android拍照得到全尺寸图片并进行压缩/拍照或者图库选择 压缩后 图片 上传
    Toolbar自定义布局
    [致歉]2:05-6:35部分站点出现故障,给您带来麻烦,请谅解团队
    上周热点回顾(8.11-8.17)团队
    [网站公告]8月17日14:00-15:00(周日下午)发布新版站内短消息团队
  • 原文地址:https://www.cnblogs.com/wuchanming/p/3932643.html
Copyright © 2020-2023  润新知