自学内容网 自学内容网

vector的模拟实现

1. 模拟实现

由于实现的是一个类模板,那么可以先写处以下代码

namespace cx
{
template<class T>
class vector
{

private:
}
}

1.1 成员变量

vector的成员变量为三个指针。含义如下

start; //指向开始
finish; //指向最后数据的下一个
end_of_storage; //指向最大容量的后一个位置

在这里插入图片描述
指针指向的数据类型为T,因此指针的类型为T*
在内部可以加入一条typedef,这也是迭代器的需要。

typedef T* iterator;

这样我们的代码就成了这样

namespace cx
{
    template<class T>
    class vector
    {
    public:
        typedef T* iterator;


    private:
        iterator start;                     //指向开始
        iterator finish;                    //指向最后数据的下一个
        iterator end_of_storage;        //指向最大容量的后一个位置
    };
}

接下来就实现成员函数。

1.2 成员函数

构造函数

只需要将三个指针初始化为nullptr即可

vector()
    :start(nullptr)
    ,finish(nullptr)
    ,end_of_storage(nullptr)
{}

插入和删除

当空间不够时(finish==end_of_storage),需要扩容。
而insert时,扩容会导致迭代器失效。
在这里插入图片描述
所以在insert扩容时,需要保留一下pos和start的距离。

而erase时,如果删除pos位置的数据,那么也认为迭代器失效了。

void reserve(size_t capacity)
{
    if (this->capacity() < capacity)
    {
        size_t old_size = this->size();
        T* tmp = new T[capacity];
        //memcpy(tmp, this->start,sizeof(T)*old_size);     //本质浅拷贝,会导致堆空间多次析构
        for (size_t i = 0; i < old_size; ++i)
        {
            tmp[i] = this->start[i];
        }
        delete[] this->start;
        this->start = tmp;
        this->finish = tmp + old_size;
        this->end_of_storage = tmp + capacity;
    }
}

void resize(size_t size)
{
    finish = start;
    finish += size;
}

//尾插,尾删
void push_back(const T& val)
{
    if (this->finish == this->end_of_storage)
    {
        size_t new_capacity = this->capacity() == 0 ? 2 : this->capacity() * 2;
        reserve(new_capacity);
    }
    *this->finish = val;
    this->finish++;
}

void pop_back()
{
    assert(size() > 0);
    --finish;
}

//pos位置插入和删除
iterator insert(iterator pos, const T& val)
{
    assert(pos >= start);
    assert(pos <= finish);

    if (finish == end_of_storage)
    {
        //扩容会导致迭代器失效
        size_t leng = pos - this->start;

        size_t new_capacity = this->capacity() == 0 ? 2 : this->capacity() * 2;
        reserve(new_capacity);

        pos = this->start + leng;
    }

    iterator end = finish;
    while (end > pos)
    {
        *end = *(end-1);
        --end;
    }
    *pos = val;
    ++finish;

    return pos;
}
//删除后,认为迭代器失效
iterator erase(iterator pos)
{
    assert(pos >= start);
    assert(pos < finish);

    iterator begin = pos + 1;
    while (begin < finish)
    {
        *(begin - 1) = *begin;
        ++begin;
    }

    --finish;

    return pos;
}

其他

//num个val值初始化
vector(size_t num, const T& val = T())
{
    reserve(num);
    for (size_t i = 0; i < num; ++i)
    {
        push_back(val);
    }
}

vector(int num, const T& val = T())
{
    reserve(num);
    for (int i = 0; i < num; ++i)
    {
        push_back(val);
    }
}
vector(const vector<T>& v)
{
   reserve(v.capacity());
   for (auto e : v)
   {
       push_back(e);
   }
}

//析构函数
~vector()
{
   delete[] start;
   start = finish = end_of_storage = nullptr;
}

//  [ ] 重载
const T& operator[](size_t pos) const
{
   return start[pos];
}

T& operator[](size_t pos)
{
   return start[pos];
}

bool empty() const
{
   return size() == 0;
}

//大小和容量
size_t size() const
{
   return finish - start;
}

size_t capacity() const
{
   return end_of_storage - start;
}
//交换
void swap(vector<T>& v)
{
   std::swap(this->start, v.start);
   std::swap(this->finish, v.finish);
   std::swap(this->end_of_storage, v.end_of_storage);
}

//赋值重载
vector<T>& operator= (const vector<T>& v)
{
   reserve(v.capacity());
   for (size_t i = 0; i < v.size(); ++i)
   {
       start[i] = v[i];
   }
   finish = start;
   finish += v.size();
   end_of_storage = start;
   end_of_storage += v.capacity();
   return *this;
}

1.3 迭代器

迭代器。也是一个类,成员变量大多数情况是一个指针。通过对++,-- ,*,->,==,!=等运算符重载,使得遍历数据时,有一个统一的方法。它不关注容器底层的实现细节和结构。
这也是封装的体现。

 template<class Iterator,class ptr,class ref>
 class Reverse_Iterator
 {
 public:

     typedef Reverse_Iterator<Iterator,ptr,ref> self;

     Reverse_Iterator(Iterator it)
         :_it(it)
     {}

     self& operator++()
     {
         _it--;
         return *this;
     }

     self operator++(int)
     {
         self tmp(_it);
         _it--;
         return tmp;
     }

     ref operator*()
     {
         return *_it;
     }

     ptr operator->()
     {
         return &(*_it);
     }

     bool operator!=(const self& rit)
     {
         return _it != rit._it;
     }

 private:
     Iterator _it;   
 };

而const迭代器,不允许修改数据,它和普通迭代器的差别只有重载*和->的返回值。因此增加两个模板参数,通过传不同的类型,实现出不同的类。

在vector类内,将迭代器添加进去即可,最终代码如下。

#pragma once
#include<assert.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<string>
using namespace std;

namespace cx
{
    template<class Iterator,class ptr,class ref>
    class Reverse_Iterator
    {
    public:

        typedef Reverse_Iterator<Iterator,ptr,ref> self;

        Reverse_Iterator(Iterator it)
            :_it(it)
        {}

        self& operator++()
        {
            _it--;
            return *this;
        }

        self operator++(int)
        {
            self tmp(_it);
            _it--;
            return tmp;
        }

        ref operator*()
        {
            return *_it;
        }

        ptr operator->()
        {
            return &(*_it);
        }

        bool operator!=(const self& rit)
        {
            return _it != rit._it;
        }

    private:
        Iterator _it;   
    };

    template<class T>
    class vector
    {
    public:
        typedef T* iterator;
        typedef const T* const_iterator;

        typedef Reverse_Iterator<iterator,T*,T&> reverse_iterator;
        typedef Reverse_Iterator<const_iterator,const T*,const T&> const_reverse_iterator;

        //迭代器
        iterator begin()
        {
            return start;
        }

        iterator end()
        {
            return finish;
        }

        const_iterator begin() const
        {
            return start;
        }

        const_iterator end() const
        {
            return finish;
        }

        reverse_iterator rbegin()
        {
            return reverse_iterator(end() - 1);
        }

        reverse_iterator rend()
        {
            return reverse_iterator(begin() - 1);
        }

        const_reverse_iterator rbegin() const
        {
            return const_reverse_iterator(end() - 1);
        }

        const_reverse_iterator rend() const
        {
            return const_reverse_iterator(begin() - 1);
        }

        //默认构造
        vector()
            :start(nullptr)
            ,finish(nullptr)
            ,end_of_storage(nullptr)
        {}

        //num个val值初始化
        vector(size_t num, const T& val = T())
        {
            reserve(num);
            for (size_t i = 0; i < num; ++i)
            {
                push_back(val);
            }
        }

        vector(int num, const T& val = T())
        {
            reserve(num);
            for (int i = 0; i < num; ++i)
            {
                push_back(val);
            }
        }

        //迭代器区间初始化
        template<class input_iteartor>
        vector(input_iteartor first, input_iteartor last)
        {
            while (first != last)
            {
                push_back(*first);
                first++;
            }
        }

        vector(initializer_list<T> list)
        {
            reserve(list.size());
            for (auto e : list)
            {
                push_back(e);
            }
        }

        vector(const vector<T>& v)
        {
            reserve(v.capacity());
            for (auto e : v)
            {
                push_back(e);
            }
        }

        //析构函数
        ~vector()
        {
            delete[] start;
            start = finish = end_of_storage = nullptr;
        }

        //  [ ] 重载
        const T& operator[](size_t pos) const
        {
            return start[pos];
        }

        T& operator[](size_t pos)
        {
            return start[pos];
        }

        bool empty() const
        {
            return size() == 0;
        }

        //大小和容量
        size_t size() const
        {
            return finish - start;
        }

        size_t capacity() const
        {
            return end_of_storage - start;
        }

        void reserve(size_t capacity)
        {
            if (this->capacity() < capacity)
            {
                size_t old_size = this->size();
                T* tmp = new T[capacity];
                //memcpy(tmp, this->start,sizeof(T)*old_size);     //本质浅拷贝,会导致堆空间多次析构
                for (size_t i = 0; i < old_size; ++i)
                {
                    tmp[i] = this->start[i];
                }
                delete[] this->start;
                this->start = tmp;
                this->finish = tmp + old_size;
                this->end_of_storage = tmp + capacity;
            }
        }

        void resize(size_t size)
        {
            finish = start;
            finish += size;
        }

        //尾插,尾删
        void push_back(const T& val)
        {
            if (this->finish == this->end_of_storage)
            {
                size_t new_capacity = this->capacity() == 0 ? 2 : this->capacity() * 2;
                reserve(new_capacity);
            }
            *this->finish = val;
            this->finish++;
        }

        void pop_back()
        {
            assert(size() > 0);
            --finish;
        }

        //pos位置插入和删除
        iterator insert(iterator pos, const T& val)
        {
            assert(pos >= start);
            assert(pos <= finish);

            if (finish == end_of_storage)
            {
                //扩容会导致迭代器失效
                size_t leng = pos - this->start;

                size_t new_capacity = this->capacity() == 0 ? 2 : this->capacity() * 2;
                reserve(new_capacity);

                pos = this->start + leng;
            }

            iterator end = finish;
            while (end > pos)
            {
                *end = *(end-1);
                --end;
            }
            *pos = val;
            ++finish;

            return pos;
        }
        //删除后,认为迭代器失效
        iterator erase(iterator pos)
        {
            assert(pos >= start);
            assert(pos < finish);

            iterator begin = pos + 1;
            while (begin < finish)
            {
                *(begin - 1) = *begin;
                ++begin;
            }

            --finish;

            return pos;
        }

        //交换
        void swap(vector<T>& v)
        {
            std::swap(this->start, v.start);
            std::swap(this->finish, v.finish);
            std::swap(this->end_of_storage, v.end_of_storage);
        }

        //赋值重载
        vector<T>& operator= (const vector<T>& v)
        {
            reserve(v.capacity());
            for (size_t i = 0; i < v.size(); ++i)
            {
                start[i] = v[i];
            }
            finish = start;
            finish += v.size();
            end_of_storage = start;
            end_of_storage += v.capacity();
            return *this;
        }


    private:
        iterator start;                     //指向开始
        iterator finish;                    //指向最后数据的下一个
        iterator end_of_storage;     //指向最大容量的后一个位置
    };                                             
    
}


原文地址:https://blog.csdn.net/qq_74245477/article/details/140710399

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!