美文网首页
VecStr(模仿vector容器)

VecStr(模仿vector容器)

作者: 峡迩 | 来源:发表于2017-09-09 19:12 被阅读0次
    // Vecstr.cpp :模拟vector容器,但是仅仅对string有效!
    //
    
    #include "stdafx.h"
    #include<string>
    #include<iostream>
    #include<vector>
    #include<memory>
    #include<utility>
    #include<algorithm>
    
    using namespace std;
    
    class VecStr
    {
    public:
        VecStr():elements(nullptr),first_free(nullptr),cap(nullptr) {}
    
        //VecStr(const VecStr &rh):elements(rh.elements),first_free(rh.first_free),cap(rh.cap){}这没有拷贝元素!
        VecStr(const VecStr &rh)
        {
            auto newdata = alloc_n_copy(rh.begin(), rh.end());
            elements = newdata.first;
            first_free = cap = newdata.second;
        }
        VecStr operator=(const VecStr &rh)
        {
            auto data = alloc_n_copy(rh.begin(), rh.end());//拷贝
            free();     //释放原对象!alloc申请的两块空间不相同,所以可以释放!
            elements = data.first;
            first_free = cap = data.second;
            return *this;
        }
    
        //只有当一个类没有为自己定义任何拷贝控制成员,且类的每个非static数据成员都可以移动,编译器才会自动合成移动构造函数和赋值函数。对于所有内置成员,都含有移动操作!
    
        VecStr(const VecStr &&rh) noexcept:elements(rh.elements),first_free(rh.first_free),cap(rh.cap)
        {
            elements = first_free = cap = nullptr;          //确保原对象不再指向移动后的源!
        }
        VecStr& operator=(const VecStr &&rh) noexcept
        {
            if (&rh != this)
            {
                free();         //释放现有资源
                elements = rh.elements;
                first_free = rh.first_free;
                cap = rh.cap;
                elements = first_free = cap = nullptr;
            }
            return *this;
        }
        ~VecStr() { free(); }
    
        void push_back(const string &s);
        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:
        string *elements;
        string  *first_free;
        string *cap;
        static std::allocator<std::string> alloc;       //此为声明语句
        pair<string*, string*> alloc_n_copy(const string *lh, const string *rh);
        void check_n_alloc()
        {
            if (size() == capacity())
            {
                reallocate();       //重新分配内存!
            }
        }
        void free();
        void reallocate();
    };
    
    void VecStr::push_back(const string &s)
    {
        check_n_alloc();
        alloc.construct(first_free++,s);        //在first_free处构造字符串s!
    }
    pair<string*, string*> VecStr::alloc_n_copy(const string *lh, const string *rh)
    {
        auto data = alloc.allocate(rh - lh);            //拷贝lh至rh范围的元素;
        return { data,uninitialized_copy(lh,rh,data) };//uninitialized_copy将lh至rh范围内的元素拷贝至data!返回首地址data和尾地址!
    }
    void VecStr::free()
    {
        if (elements)
        {
            for (auto p = first_free; p != elements;)
                alloc.destroy(--p);
            alloc.deallocate(elements, cap - elements);
        }
    }
    void VecStr::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)//此部分内容可以改为auto dest=uninitialized_copy(make_move_iterator(begin()),make_move_iterator(end()),first)  ,返回first_free位置!(make_move_iterator将普通迭代器转为移动迭代器!)
            alloc.construct(dest++, std::move(*elem++));
        free();//此时释放的什么?
        elements = newdata;
        first_free = dest;
        cap = elements + newcapacity;
    }
    
    allocator<std::string> VecStr::alloc;
    //静态成员不属于类的任何一个对象,一般来说我们不能在类内部初始化静态成员。相反的,必须在类的外部定义和初始化每个静态成员。和其他对象一样,一个静态成员只能定义一次!
    //静态成员在类内初始化只允许static constexpr int period=30;即是在类内初始化了,也需要在类外定义以下该成员constexpr int Account::period!另外,静态成员可以在类中作为函数的实参!
    int main()
    {
    
        //const vector<string> v = { "string" ,"a"};
        allocator<string> a;
        auto b1=a.allocate(200);
        //a.construct(b1, "asd");
        //a.construct(++b1, "adsf");
    
        auto b2 = a.allocate(200);
        cout << b1-b2;
        return 0;
    }
    
    

    相关文章

      网友评论

          本文标题:VecStr(模仿vector容器)

          本文链接:https://www.haomeiwen.com/subject/sujajxtx.html