STL源码剖析读书笔记

Vector源码

准备工作:

C++标准库「memory」,用它的Allocator类来作配置器

allocate(std::size_t n, const void * hint)

参数:

size_t n - 为其分配存储空间的对象数量

const void* hint - 指向附近内存位置的指针

返回指向适当对齐的内存块的第一个字节的指针,并且足以容纳一个n类型的对象数组T

std :: uninitialized_fill( ForwardIt first, ForwardIt last, const T& value)

参数:

ForwardIt first,ForwardIt last - 要初始化的元素的范围
const T& value - 用来构造元素的值

uninitialized_copy(InputIt first, InputIt last, ForwardIt d_first );

参数:

irst, last -    要复制的元素范围
d_first -    目标范围的起始

copy_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last )

参数:

first, last    -    要复制的元素范围
d_last    -    目标范围的结尾。

返回指向最后复制元素的迭代器

void construct (U* p, Args&&... args);

参数:

p - 指向具有足够存储空间以包含U类型元素的位置的指针。
ARGS - 转发给构造函数的参数。参数是零个或多个类型的列表。

定义vector的嵌套类型

typedef T                       value_type;
typedef value_type*             iterator;
typedef const value_type*       const_iterator;
typedef value_type&             reference;
typedef value_type*             pointer;
typedef size_t                  size_type;    
typedef ptrdiff_t               difference_type; //ptrdiff_t通常用来保存两个指针减法的结果,这里用来定义两个迭代器的距离

定义迭代器(指针)

iterator _start;                   
iterator _end;                      
iterator _end_of_storage; //当前可用空间的尾

vector类的构造函数

Vector() :_begin(0), _end(0), _end_of_storage(0){}
Vector(size_type n, const T& value);
Vector(size_type n);  
Vector(iterator first, iterator last);
Vector(const myVector& v); 
Vector& operator=(const myVector& rhs);

vector容器的操作

iterator begin() { return _begin; }
iterator end() { return _end; }
const_iterator cbegin() const { return _start; }       
const_iterator cend() const { return _end; }

size_type size()  { return size_type(end() - begin()); }     
size_type capacity() { return size_type(_end_of_storage - begin()); }
bool empty() { return begin() == end(); }
void swap(myVector &other);


reference front() { return *begin(); }
reference back() { return *(end() - 1); }
reference operator[] (size_type n) { return *(begin() + n); }
reference at(size_type index) { return *(index() + index); }


void insert_aux(iterator positon, const T& x);
void push_back(const T& value);
void pop_back();
void insert(iterator position, size_type n, const T& x);  

iterator erase(iterator position);
iterator erase(iterator first, iterator last); 
void clear() { erase(begin(), end()); }

完整代码:

#ifndef Vector_H
#define Vector_H
#include <iostream>
#include <memory>
#include <algorithm>

template <class T, class Allocator = std::allocator<T>> class Vector {
public:
    typedef T                   value_type;
    typedef value_type*         iterator;
    typedef const value_type*   const_iterator;
    typedef value_type&         reference;
    typedef value_type*         pointer;
    typedef size_t              size_type;
    typedef ptrdiff_t           difference_type;
protected:
    std::allocator<value_type> _alloc;
    iterator _begin;
    iterator _end;
    iterator _end_of_storage;
public:
    Vector(): _begin(0),_end(0),_end_of_storage(0){};
    Vector(size_type n,const T& value);
    Vector(size_type n);
    Vector(iterator first,iterator last);
    Vector(const Vector& v);
    Vector& operator=(const Vector& ass);
    ~Vector(){_destroy();}

    iterator begin() {return _begin;}
    iterator end() {return _end;}
    const_iterator kbegin() {return _begin;}
    const_iterator kend() {return _end;}

    size_type size() {return size_type(end() - begin());};
    size_type capacity() {return size_type(_end_of_storage - begin());}
    bool empty() {return begin() == end();}
    void swap(Vector &other_element);

    reference front() {return *begin();}
    reference back() {return *(end() - 1);}
    reference operator[](size_type index) {return *(begin() + index);}
    reference at(size_type index) {return *(begin() + index);}

    void insert_auxiliary(iterator position, const T& x);
    void push_back(const T& value);
    void pop_back();
    void insert(iterator position,size_type n,const T& x);

    iterator erase(iterator position);
    iterator erase(iterator first,iterator last);
    void clear() {erase(begin(),end());}

    void _destroy();
};



Vector<T,Allocator>::Vector(size_type n,const T& value) {
    _begin = _alloc.allocate(n);
    std::uninitialized_fill(_begin, _begin + n, value);
    _end = _end_of_storage = _begin + n;
}


Vector<T,Allocator>::Vector(size_type n) {
    _begin = _alloc.allocate(n);
    std::uninitialized_fill(_begin, _begin + n, 0);
    _end = _end_of_storage = _begin + n;
}



void Vector<T,Allocator>::swap(Vector &other_element) {
    std::swap(_begin, other_element.begin());
    std::swap(_end, other_element.end());
    std::swap(_end_of_storage, other_element._end_of_storage);
}


Vector<T,Allocator> &Vector<T,Allocator>::operator=(const Vector& ass) {
    if (this == &ass) {
        return *this;
    }
    size_type n = ass.kend() - ass.kbegin();
    _begin = _alloc.allocate(n);
    _end = _end_of_storage = std::uninitialized_copy(ass.kbegin(), ass.kend(), _begin);
}


void Vector<T,Allocator>::insert(iterator position,
                                 size_type n,const T& x) {
    if (n >= 0) {
        if (_end_of_storage - _end >= n) {
            T x_copy = x;
            const size_type element_after = _end - position;
            iterator old_end = _end;
            if (element_after > n) {
                uninitialized_copy(_end - n,old_end - n,_end);
                _end = _end + n;
                copy_backward(position,old_end - n,old_end);
                fill(position,position + n,x_copy);
            } else {
                uninitialized_fill_n(_end,n - element_after,x_copy);
                _end += n - element_after;
                uninitialized_copy(position,old_end,_end);
                _end += element_after;
                fill(position,old_end,x_copy);
            }
        }
    } else {
        const size_type old_size = size();
        const size_type length = old_size + std::max(old_size,n);
        iterator new_begin = _alloc.allocate(length);
        iterator new_end = new_begin;
        new_end = uninitialized_copy(_begin,position,new_begin);
        new_end = uninitialized_fill_n(position,_end,new_end);
        _destroy();
        _begin = new_begin;
        _end = new_end;
        _end_of_storage = new_begin + length;
    }
}


void Vector<T,Allocator>::insert_auxiliary(iterator position, const T& x) {
    if (_end != _end_of_storage) {
        //pass
    } else {
        const size_type old_size = size();
        const size_type length = old_size ? 2 * old_size : 1;
        iterator new_begin = _alloc.allocate(length);
        iterator new_end = new_begin;
        new_end = uninitialized_copy(_begin,position,new_begin);
        _alloc.construct(new_end, x);
        ++new_end;
        new_end = uninitialized_copy(position,_end,new_end);

        _destroy();

        _begin = new_begin;
        _end = new_end;
        _end_of_storage = new_begin + length;

    }
}


void Vector<T,Allocator>::push_back(const T& value) {
    if (_end != _end_of_storage) {
        _alloc.construct(_end, value);
        ++_end;
    } else {
        insert_auxiliary(end(), value);
    }
}


typename Vector<T,Allocator>::iterator
Vector<T,Allocator>::erase(iterator first,iterator last) {
    difference_type left = _end - last;
    std::copy(last, _end, first);
    iterator now(first + left);
    while (_end != now) {
        _alloc.destroy(--_end);
    }
    return first;
}


void Vector<T,Allocator>::_destroy() {
    if (_begin) {
        iterator it(_end);
        while (it != _begin) {
            _alloc.destroy(--it);
        }
    }
    _alloc.deallocate(_begin, _end_of_storage - _begin);
    _begin = _end_of_storage = _end = NULL;
}

#endif
#笔记##读书笔记#
全部评论

相关推荐

头像
01-12 14:44
已编辑
百度_高级研发工程师
今天看到了某平台攻击牛友的帖子,段段今天打算为牛友们说句话,我们的努力到底有没有意义。&nbsp;(原文复述:感觉牛客就是当年那群做题区毕业了开始找工作还收不住那股味,颇有一种从年级第一掉到年纪第二后抱怨考不上大学的区味)&nbsp;&nbsp;粗鄙,无礼,傲慢,攻击,在这里我没有看到任何有用的分析,我只看到了屁股决定脑袋的攻击,我只看到了嫉妒和眼红。一、去医院不看病你去逛街吗&nbsp;去医院你不去看病你去逛街吗?去加油站不加油你去抽烟吗?去部队你不训练战斗技能你去养老吗?来牛客你不努力求职你来干什么来了。&nbsp;牛客本身就是个求职平台,大家分享有用的知识,分享面经,分享offer,分享求职经验的,来牛客不就干这个来了吗?有什么问题吗?...
给个好点的工作吧啊啊...:不知道我看的是不是和博主同样的帖子,我记得原帖是表达的是有些匿名老是发几十万的offer侮辱价,然后就有牛友觉得凡尔赛了导致后面的评论有些偏激。我觉得这个最近闫学晶那个事情有点类似了,她说他儿子一年只能赚七八十万家庭生活都难以为继,不说普通家庭,多少大厂的程序员都赚不到这个数字,大部分家庭看到这种发言肯定会难受的一p,生活的担子又这么重,人都是需要发泄情绪的,互联网就是个极佳的载体,所以很多人直接就喷她了,人在情绪发泄的时候是不思考的,否则就不叫发泄了。然后还有一个点,段哥假定了这些喷的人全都是“躺平的”,这点可能有失偏颇,很多人一直在努力,但是始终缺乏天时地利人和的某一个条件,这点相信段哥找工作的过程中深有体会。绝大部分人都以结果的失败去否认了努力的全过程,可能只是别人努力的方向错了。就像一次面试,可能你准备了很久,结果面试官就是比较奇葩,一直问没有学习到的领域或知识点,然后有人凭一个挂掉的结果就直接给你扣了一个“躺平”的帽子,觉得挂掉是你不够努力,您心里滋味如何?再说点近点的,我也是od,多少同事深夜无偿加班,涨过一分工资吗?多少外包的技术大牛因为学历被困在外包,连od都进不去,这些人难道不努力吗?只是限制与生活、公司制度等等之类的无奈罢了。说到努力,又想到李家琦79元眉笔事件,这么多年有没有认真工作?有没有涨工资?他嘴里说出来是那么的理所当然,打工牛马都知道“任劳任怨”,“认真工作”真能涨工资?只干活不发声就等着被摘果子吧,企业里永远都是“汇报杰出者”升的最快(当然不是所有企业),这种事情相信段哥包括我甚至大部分od都经历过。最近辞职回老家,和老爸散步每次他都会感慨街上的蔬菜小贩多不容易,他们晚上就窝在那种三轮小货车的驾驶室里,腿都伸不直,我们这里晚上零下了,只盖一条薄毛毯,始终舍不得住我们镇上几十块的酒店,因为一车蔬菜就赚几百块顶多一千而且要卖好久,这样的例子还有太多了。这种芸芸众生可能辛苦了一天之后,打开手机看到网上的凡尔赛发言,跟风喷了几句发泄情绪,我觉得这种人不应该扣上“躺平”的帽子。我觉得大部分正常人都是努力的,或者曾经努力过,但世界上有太多努力解决不了的无奈了,甚至说你都没有那个努力的机会,不过正因如此,才显得坚持不懈的努力奋斗之人的难得可贵,认清生活的真相后仍然热爱生活,敢于直面现实的淋漓。
段段STEADY觉醒与突...
点赞 评论 收藏
分享
评论
点赞
6
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务