手撕简易版的vector

说明:本文vector手撕仿照的是库函数实现,利用迭代器作为私有成员

private: typedef T* iterator;

iterator _start = nullptr;

iterator _finish = nullptr;

iterator _end_of_storage = nullptr;
(1)构造和析构

注: // 构造采用默认参数,强制编译器生成

cpp 复制代码
vector() = default;
        ~vector()
        {
            if (_start)
                delete[] _start;
            _start = _finish = _end_of_storage = nullptr;
            cout << "~vector()" << endl;
        }

(2)//拷贝构造和赋值重载

注: //拷贝构造直接尾插

//赋值重载直接现代写法

cpp 复制代码
vector(const vector<T>& v)
		{
			reserve(v.capacity());
			for (auto e : v)
			{
				push_back(e);
			}
		}
        void swap(vector<T> v)
        {
            std::swap(_start,v._start);
            std::swap(_finish,v._finish);
            std::swap(_end_of_storage,v._end_of_storage);
        }
        vector<T>&operator=(vector<T> v)
        {
            swap(v);
            return *this;
        }

(3)//有效长度和开辟的大小空间

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

const size_t capacity()const { return _end_of_storage - _start; }
(4)//范围for,实现迭代器

//这里使用T*充当迭代器,并不是所有的函数迭代器都是T*,迭代器可以屏蔽底层代码细节

cpp 复制代码
iterator begin() { return _start; }
        iterator end() { return _finish; }
        const iterator begin() const{return _start;}
		const iterator end() const {return _finish;}

(5)//插入和删除等相关函数

注: //库函数的参数为迭代器,因此会引入扩容和删除会引发迭代器失效问题,所以返回更新后的迭代器进行迭代器的更新

//扩容

//问题:

//(1)移动数据时,memcpy是浅拷贝,所以涉及到深拷贝的内容如vector<string>,析构原空间时会造成数据string的析构

//此时便会引发数据销毁等野指针问题

//(2)更新_finish时,由于_start已经指向新地方所以原size(_finish-_start)也会变化,所以要保存原数据的大小

cpp 复制代码
void reserve(size_t n)
        {
            if (n > capacity())
            {
                iterator tmp = new T[n];
                //保存原数据大小
                size_t oldsize = size();
                // memcpy(tmp,_start);
                for (int i = 0; i < oldsize; i++)
                {
                    tmp[i] = _start[i];
                }
                delete[] _start;
                _start = tmp;
                _finish = _start + oldsize;
                _end_of_storage = _start + n;
            }
        }
        iterator insert(iterator pos, const T& val)
        {
            assert(pos >= begin() && pos <= end());
            size_t n = pos - _start;
            if (_finish == _end_of_storage)
            {
                reserve(capacity() == 0 ? 4 : capacity() * 2);
                pos = _start + n;
            }
            size_t end = size();
            while (end > n)
            {
                _start[end] = _start[end - 1];
                end--;
            }
            _start[n] = val;
            _finish++;
            return pos;
        }
        iterator erase(iterator pos)
        {
            assert(pos >= begin() && pos <= end());
            size_t end = pos - _start + 1;
            while (end < size())
            {
                _start[end - 1] = _start[end];
                end++;
            }
            _finish--;
            return pos;
        }
        void push_back(const T& val)
        {
            insert(end(), val);
        }
        void pop_back()
        {
            erase(end() - 1);
        }

(6)所有代码:

cpp 复制代码
#include <iostream>
#include <cassert>
using namespace std;

namespace Myvector
{
    // 仿照库函数实现简易版的vector,学习并理解其底层原理
    template <class T>
    class vector
    {
        typedef T* iterator;

    public:
        // 构造与析构
        // 构造采用默认参数,强制编译器生成
        vector() = default;
        ~vector()
        {
            if (_start)
                delete[] _start;
            _start = _finish = _end_of_storage = nullptr;
            cout << "~vector()" << endl;
        }

        //拷贝构造和赋值重载
        //拷贝构造直接尾插
        //赋值重载直接现代写法
        vector(const vector<T>& v)
		{
			reserve(v.capacity());
			for (auto e : v)
			{
				push_back(e);
			}
		}
        void swap(vector<T> v)
        {
            std::swap(_start,v._start);
            std::swap(_finish,v._finish);
            std::swap(_end_of_storage,v._end_of_storage);
        }
        vector<T>&operator=(vector<T> v)
        {
            swap(v);
            return *this;
        }
        //有效长度和开辟的大小空间
        const size_t size()const { return _finish - _start; }
        const size_t capacity()const { return _end_of_storage - _start; }

        //范围for,实现迭代器
        //这里使用T*充当迭代器,并不是所有的函数迭代器都是T*,迭代器可以屏蔽底层代码细节
        iterator begin() { return _start; }
        iterator end() { return _finish; }
        const iterator begin() const{return _start;}
		const iterator end() const {return _finish;}

        //插入和删除等相关函数
        //库函数的参数为迭代器,因此会引入扩容和删除会引发迭代器失效问题,所以返回更新后的迭代器进行迭代器的更新
        //扩容
        //问题:
        //(1)移动数据时,memcpy是浅拷贝,所以涉及到深拷贝的内容如vector<string>,析构原空间时会造成数据string的析构
        //此时便会引发数据销毁等野指针问题
        //(2)更新_finish时,由于_start已经指向新地方所以原size(_finish-_start)也会变化,所以要保存原数据的大小
        void reserve(size_t n)
        {
            if (n > capacity())
            {
                iterator tmp = new T[n];
                //保存原数据大小
                size_t oldsize = size();
                // memcpy(tmp,_start);
                for (int i = 0; i < oldsize; i++)
                {
                    tmp[i] = _start[i];
                }
                delete[] _start;
                _start = tmp;
                _finish = _start + oldsize;
                _end_of_storage = _start + n;
            }
        }
        iterator insert(iterator pos, const T& val)
        {
            assert(pos >= begin() && pos <= end());
            size_t n = pos - _start;
            if (_finish == _end_of_storage)
            {
                reserve(capacity() == 0 ? 4 : capacity() * 2);
                pos = _start + n;
            }
            size_t end = size();
            while (end > n)
            {
                _start[end] = _start[end - 1];
                end--;
            }
            _start[n] = val;
            _finish++;
            return pos;
        }
        iterator erase(iterator pos)
        {
            assert(pos >= begin() && pos <= end());
            size_t end = pos - _start + 1;
            while (end < size())
            {
                _start[end - 1] = _start[end];
                end++;
            }
            _finish--;
            return pos;
        }
        void push_back(const T& val)
        {
            insert(end(), val);
        }
        void pop_back()
        {
            erase(end() - 1);
        }
    private:
        iterator _start = nullptr;
        iterator _finish = nullptr;
        iterator _end_of_storage = nullptr;
    };

};

int main()
{
    Myvector::vector<int> v1;
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    v1.push_back(5);
    v1.push_back(6);
    for (auto& e : v1)
    {
        cout << e << " ";
    }
    cout << endl;
    v1.pop_back();
    v1.pop_back();
    v1.pop_back();
    v1.pop_back();
    for (auto& e : v1)
    {
        cout << e << " ";
    }
    cout << endl; 
    return 0;
}
相关推荐
你撅嘴真丑4 小时前
第八章 - 贪心法
开发语言·c++·算法
u0109272714 小时前
模板元编程调试方法
开发语言·c++·算法
2401_838472515 小时前
C++图形编程(OpenGL)
开发语言·c++·算法
-dzk-5 小时前
【代码随想录】LC 203.移除链表元素
c语言·数据结构·c++·算法·链表
Trouvaille ~5 小时前
【Linux】线程同步与互斥(三):生产者消费者模型实战
linux·运维·c++·信号量·阻塞队列·生产者消费者模型·环形队列
Queenie_Charlie5 小时前
八皇后问题
c++·深度优先搜索
m0_736919105 小时前
编译器命令选项优化
开发语言·c++·算法
Jiu-yuan5 小时前
C++函数
c++
naruto_lnq6 小时前
C++中的工厂方法模式
开发语言·c++·算法