C++项目:my_vector的裸实现

2023-12-27 15:20:13

引言

这里为什么标题要叫做裸实现呢,这是因为这是自己在没有看任何参考源码和任何规范什么乱七八糟的前提下,通过自己对vector的理解,然后码出来的一个小项目,所以看起来比较粗糙吧,然后也算是自己实现的第一个小项目,然后之后要不断写才行啊,日后想继续写个更规范的vector,string,对象池甚至是智能指针。

一、遇到的难点

    1. 不能把模板类的.hpp和.cpp文件分开放,否则会编译不通过的
    1. 在类中,静态(整型)数据成员才可以在类中声明一个数,static const double a = 1.5不可以,但可以static constexpr double a = 1.5,原因在于C++ 标准没有指定浮点应该如何实现,而是留给处理器。为了解决这个问题和其他限制constexpr而引入。
    1. 在使用缺省值时,在声明中给就行了,在定义中给的话会报错

二、GitHub地址

GitHub地址

三、my_vector.hpp

#ifndef MY_VECTOR_HPP
#define MY_VECTOR_HPP
#include <unistd.h>
#include <iostream>
#include <cassert>

template <typename T>
class my_vector
{
private:
    static const size_t INIT_SIZE = 15; // 初始化大小
    static constexpr double INCREMENT_SIZE = 1.5;  //只有静态常量(整型)数据成员才可以在类中初始化

public:
    my_vector(const int s = 0)
    {
        size_t len = s > INCREMENT_SIZE ? s : INCREMENT_SIZE;
        _ptr = new T[len];
        _size = 0;
        _capacity = len;
    }

    my_vector(const my_vector &other):_size(other._size),_capacity(other._capacity)
    {
        _ptr = new T[_capacity];
        for(int i = 0; i < _size; ++i)
        {
            _ptr[i] = other[i];
        }
    }

    ~my_vector()
    {
        delete[] _ptr;
        _ptr = nullptr;
        _size = _capacity = 0;
    }

public:
    const T &at(const size_t index) const // 同时进行越界检查
    {
        assert(index >= 0 && index < _size);
        return _ptr[index];
    }

    T &operator[](const size_t index) const
    {
        return _ptr[index];
    }

    T &operator=(const my_vector &other) //
    {
        _size = other._size;
        _capacity = other._capacity;
        _ptr = new T[_capacity];
        for(int i = 0; i < _size; ++i)
        {
            _ptr[i] = other[i];
        }
    }

    T &front() const
    {
        assert(!empty());
        return _ptr[0];
    }

    T &back() const
    {
        assert(!empty());
        return _ptr[_size - 1];
    }

    T *data() const
    {
        return _ptr;
    }
    bool empty() const
    {
        return _size == 0;
    }

    int size() const
    {
        return _size;
    }

    int max_size() const
    {
        return _capacity - _size;
    }

    void reserver(const int len)
    {
        if (len <= _size)
            return;

        delete[] _ptr;
        _ptr = new T[len];
        _capacity = len;
    }

    size_t capacity() const
    {
        return _capacity;
    }

    void clear()
    {
        delete[] _ptr;
        _size = 0;
    }

    void insert(const int index, const T val)
    {
        if (index < 0 || index > _size)
            return; // 假如越界就退出
        if (_size == _capacity)
        {
            increment();
        }

        for (int i = _size - 1; i >= index; --i)
        {
            _ptr[i + 1] = _ptr[i];
        }

        _ptr[index] = val;
    }

    void erase(const int i, const int sign = 0) // 0按下标删 1按第一个值删
    {
        assert(i >= 0 && i < _size);
        if (sign == 0)
        {
            for (int i = i + 1; i < _size; ++i)
            {
                _ptr[i - 1] = _ptr[i];
            }
        }
        else if (sign == 1)
        {
            for (int i = 0; i < _size; ++i)
            {
                if (_ptr[i] == i)
                {
                    for (int j = i + 1; j < _size; ++j)
                    {
                        _ptr[j - 1] = _ptr[j];
                    }
                    break;
                }
            }
        }
    }

    void push_back(const T val)
    {
        if (_size == _capacity)
            increment();

        _ptr[_size] = val;
        _size++;
    }

    void pop_back()
    {
        assert(_size > 0);

        _size--;
    }

    void resize(const size_t len)
    {
        reserve(len);
        _size = len;
    }

    void reserve(const size_t len)
    {
        if(len <= _capacity) return;
        
        T* t = _ptr;
        _ptr = new T[len];
        _capacity = len;
        for(int i = 0; i < _size; ++i)
        {
            _ptr[i] = t[i];
        }
        delete[] t;
    }

    void swap(my_vector &other) //
    {
        std::swap(_ptr, other._ptr);
        std::swap(_size, other._size);
        std::swap(_capacity, other._capacity);
    }
private:
    void increment()
    {
        T *tmp = _ptr;
        int len = _capacity * INCREMENT_SIZE;
        _ptr = new T[len];
        for (int i = 0; i < _size; ++i)
        {
            _ptr[i] = tmp[i];
        }
        _capacity = len;
        delete[] tmp;
    }

private:
    T *_ptr;
    size_t _size;
    size_t _capacity;
};
#endif

四、个人感受

关于这个项目的话其实看我的GitHub就会发现其实我很早就上传了,但是这个博客一直就创建了个草稿一直没写,我觉得这就是我的一个拖延吧,就是想做的事,知道怎么做,但一直不做,也不知道为什么,就是一个知道与做到的一个鸿沟吧,很多事情如果当时立马做了,接下来后面的一连串都会很不一样的,这就是很难,你要永远保持一个非常紧张的状态,就是时刻保持危机感,当自己想歇歇的时候,就要非常的小心,就很容易就感觉这个事已经做了的感觉,就不去做,没做但有那种已经做了的满足感,这就很不好,还是要实事求是,一直保持紧张的状态。

五、参考文献

为什么我不能将模板类的定义与其声明分开,而将其放在 .cpp 文件中?
C++参考手册
C++中类中常规变量、const、static、static const(const static)成员变量的声明和初始化

文章来源:https://blog.csdn.net/weixin_60033897/article/details/134816893
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。