设为首页 加入收藏

TOP

Vector底层实现(一)
2023-07-23 13:29:14 】 浏览:99
Tags:Vector

Vector底层实现

vector的三个私有成员

:_start   记录初始位置
, _finish 记录有效字符
, _endofstoage  记录容量大小

vector会存储的类型不同,所以要用模版来定类型 

typedef T* iterator;

iterator _start;
iterator _finish;
iterator _endofstoage;

也就是T*

 

构造函数的方法很多 可以用迭代器的范围来构造

//用迭代器构造的构造函数

传过来的是它的迭代器的类型 我们也用它的类型来接收 不比加* &

 三个属性先初始化

只要根据传过来的范围来push_back()即可

push_back函数后面会实现

        //用迭代器构造的构造函数
        template <class InputIterator>
        vector(InputIterator first, InputIterator last)
            : _start(nullptr)
            , _finish(nullptr)
            , _endofstoage(nullptr)
        {
            while (first != last)
            {
                push_back(*first);
                ++first;
            }
        }

 

构造是 也可以根据n分val来构造 所以这个功能也需要提供

传过来的是n个 用size_t接收 因为n必须是>=0的  而val是根据类型 所以用模版类型接受  

有些情况下 val会不传参  那么我们就会提供他的默认构造  (注意 在C++中,内置类型也是有默认构造的)

三个属性初始话

先用reserve函数创建n个空间

在分别push_back()添加val

        //构造n个val的构造函数
        vector(size_t n, const T& val = T())
            : _start(nullptr)
            , _finish(nullptr)
            , _endofstoage(nullptr)
        {
            reserve(n);
            for (size_t i = 0; i < n; ++i)
            {
                push_back(val);
            }
        }

 

因为某些情况 第一个参数是int  第二个参数也是int 会调用到迭代器的函数 因为这两个类型更加适配,所以会出问题,所以需要再提供一个第一个参数为int的相同函数,来避免这种情况

    //构造n个val的构造函数
        //因为用int会调用到其他函数 所以为了区分 单独写出一个第一个为int
        vector(int n, const T& val = T())
            : _start(nullptr)
            , _finish(nullptr)
            , _endofstoage(nullptr)
        {
            reserve(n);
            for (int i = 0; i < n; ++i)
            {
                push_back(val);
            }
        }

 

swap函数

这个函数是用来给拷贝构造使用

交换类的三个属性成员

        //交换
        void swap(vector<T>& v)
        {
            std::swap(_start, v._start);
            std::swap(_finish, v._finish);
            std::swap(_endofstoage, v._endofstoage);
        }

 

拷贝构造

拷贝的本质是把一个有数据的拷贝给一个无数据的,只需要用这个无数据的迭代器去调用迭代器构造,给一个临时tmp,最后再用这个无数据的与临时tmp交换  即可

因为传过来的是另一个vector 所以必须用vector<T> 接收  C++传参是特别需要注意的,真的很容易乱

        //拷贝构造
        vector(const vector<T>& v)
            : _start(nullptr)
            , _finish(nullptr)
            , _endofstoage(nullptr)
        {
            vector<T> tmp(v.begin(), v.end());//复用用迭代器构造的构造函数
            swap(tmp);
        }

 

赋值重载

v1=v2  是两个vector的数据赋值 所以它的返回值必须是vector<t>  而传参数时 也必须是vector<t> 

函数本质也是交换,所以直接调用swap  这里之所以能直接调用 而不影响到v2 是因为函数是用传值传参,它是不会影响到v2本体的,(现代写法)

返回时是返回本体 (*this)

    vector<T>& operator=(vector<T> v)//赋值重载   不用引用  现代写法
        {
            swap(v);//现代写法 
            return *this;
        }

 

析构函数

判断是否为空 当不为空时才需要析构  如果为空 去析构 会崩溃

把数据释放,并且它三个属性置空

    // 资源管理
        ~vector()
        {
            if (_start)
            {
                delete[] _start;
                _start = _finish = _endofstoage = nullptr;
            }
        }

 

迭代器部分

vector的迭代器本质就是指针  根据传进来的类型  iterator就是这个类型的指针

并且迭代器分为const版本和非const版本 

所以需要提供两个版本

        //迭代器
        typedef T* iterator;
        typedef const T* const_iterator;

 

注意 end返回的是你的实际有效字符 而不是你的的空间多大

        iterator begin()
        {
            return _start;
        }

        iterator end()
        {
            return _finish;
        }

        const_iterator begin() const
        {
            return _start;
        }

        const_iterator end() const
        {
            return _finish;
        }

 

size 

你的有效字符 _finish  而_finish实际上是有效字符的下一个位置

所以需要减去初始的位置 得到它真正的有效字符

        size_t size() const
        {
            return _finish - _start;
        }

 

capacity

计算的是vector的空间大小 也就是你的记录空间大小减去初始位置

        size_t capacity() const
        {
            return _endofstoage - _start;
        }

 

【】重载

vector是支持随意访问的,所以【】的重载必不可少

返回的是vector里存储的类型  实际上就是模版类型&nb

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++ lower_bound/upper_bound用法.. 下一篇x64dbg 插件开发SDK环境配置

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目