IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ - vector简单模拟实现 -> 正文阅读

[C++知识库]C++ - vector简单模拟实现

目录

一、整体框架

二、构造和析构函数

1.无参构造

2.迭代器区间构造

3.拷贝构造

4.赋值

5.析构

三、大小和容量相关函数

1.大小和容量

2.reserve

3.resize

四、插入和删除

1.尾插

2.尾删

3.插入

4.删除


一、整体框架

    template<class T>
    class vector
    {
    public:
        // Vector的迭代器是一个原生指针
        typedef T* iterator;
        typedef const T* const_iterator;
        iterator begin();
        iterator end();
        const_iterator cbegin() const;
        const_iterator cend() const;
        // construct and destroy
        vector();
        vector(int n, const T& value = T());

        template<class InputIterator>
        vector(InputIterator first, InputIterator last);
        vector(const vector<T>& v);
        vector<T>& operator= (vector<T> v);
        ~vector();
        // capacity
        size_t size() const;
        size_t capacity() const;
        void reserve(size_t n);
        void resize(size_t n, const T& value = T());
        ///access///
        T& operator[](size_t pos);
        const T& operator[](size_t pos) const;
        ///modify/
        void push_back(const T& x);
        void pop_back();
        void swap(vector<T>& v);
        iterator insert(iterator pos, const T& x);
        iterator erase(iterator pos);
    private:
        iterator _start; // 指向数据块的开始
        iterator _finish; // 指向有效数据的尾
        iterator _endOfStorage; // 指向存储容量的尾
    };

二、构造和析构函数

1.无参构造

? ? ? ? 将三个指针置空即可。

        vector()
            : _start(nullptr)
            , _finish(nullptr)
            , _endOfStorage(nullptr)
        {}

2.迭代器区间构造

? ? ? ? 复用尾插函数,遍历迭代器范围。

        template<class InputIterator>
        vector(InputIterator first, InputIterator last)
            :_start(nullptr)
            , _finish(nullptr)
            , _endOfStorage(nullptr)
        {
            for (InputIterator it = first; it != last; it++)
            {
                push_back(*it);
            }
        }

3.拷贝构造

? ? ? ? 利用迭代器区间构造临时的变量,与临时变量交换即可完成拷贝构造。也可以重新开空间,再进行内容的拷贝,但明显以下写法更好。

        vector(const vector<T>& v)
            : _start(nullptr)
            , _finish(nullptr)
            , _endOfStorage(nullptr)
        {
            vector<T> temp(v.cbegin(), v.cend());
            swap(temp);
        }

? ? ? ? 交换函数内容如下,交换两个实例中的指针内容。

        void swap(vector<T>& v)
        {
            std::swap(_start, v._start);
            std::swap(_finish, v._finish);
            std::swap(_endOfStorage, v._endOfStorage);
        }

4.赋值

? ? ? ? 赋值可复用参数传递中的拷贝构造,交换内部的指针即可完成赋值。

        vector<T>& operator= (vector<T> v)
        {
            swap(v);
            return *this;
        }

5.析构

? ? ? ? 释放空间,指针置空。

        ~vector()
        {
            delete[] _start;
            _start = nullptr;
            _finish = nullptr;
            _endOfStorage = nullptr;
        }

三、大小和容量相关函数

1.大小和容量

? ? ? ? 返回大小或容量,利用指针相减即可。

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

2.reserve

? ? ? ? 传入参数大于当前容量就会增容,不大于当前容量不会操作。

????????由于增容需要开辟新的空间,原来的指针指向原来的空间,因此需要提前记录指针的相对位置,保证新空间的指针正确。同时在旧的内容拷贝上不要使用memcopy浅拷贝,否则在容器存放内置类型的数据时会导致多次析构出错。

        void reserve(size_t n)
        {
            if (n > capacity())
            {
                size_t size = _finish - _start;
                T* temp = new T[n];
                if (_start)
                {
                    for (int i = 0; i < size; i++)
                    {
                        temp[i] = _start[i];
                    }
                    delete[] _start;
                }
                _start = temp;
                _finish = _start + size;
                _endOfStorage = _start + n;
            }
        }

3.resize

? ? ? ? 传入参数大于当前数据个数,对原有数据不改变,多出来的部分会初始化。如果大于当前容量,则先增容再初始化。小于当前数据个数,则会对数据进行截断。

        void resize(size_t n, const T& value = T())
        {
            if (n > size())
            {
                reserve(n);
                while (_finish != _start + n)
                {
                    *_finish = value;
                    _finish++;
                }
            }
            else
            {
                _finish = _start + n;
            }
        }

四、插入和删除

1.尾插

? ? ? ? 使用_finish指针操作即可,再扩容时如果容量为0,应给一个起始容量。

        void push_back(const T& x)
        {
            if (_finish == _endOfStorage)
            {
                reserve(capacity() == 0 ? 4 : capacity() * 2);
            }
            *_finish = x;
            _finish++;
        }

2.尾删

? ? ? ? 需要保证不会在容器为空的情况下尾删。

        void pop_back()
        {
            assert(_finish > _start);
            _finish--;
        }

3.插入

? ? ? ? 利用指针,移位数据,再将新数据插入。要考虑移位的方向会不会数据的覆盖,导致数据丢失。

        iterator insert(iterator pos, const T& x)
        {
            assert(pos >= _start);
            assert(pos <= _finish);
            if (_finish == _endOfStorage)
            {
                size_t sz = pos - _start;
                reserve(capacity() == 0 ? 4 : capacity() * 2);
                pos = _start + sz;
            }
            iterator it = _finish - 1;
            while (it != pos)
            {
                *(it + 1) = *it;
                it--;
            }
            *pos = x;
            _finish++;
            return pos;
        }

4.删除

? ? ? ? 同上,用指针对数据移位,覆盖删除的位置。

        iterator erase(iterator pos)
        {
            assert(pos >= _start);
            assert(pos < _finish);
            iterator it = pos+1;
            while (it != _finish)
            {
                *(it-1) = *it;
                it++;
            }
            _finish--;
            return pos;
        }

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:13:21  更:2022-03-15 22:15:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:24:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码