Vector容器的底层其实就是一个动态数组,内部设有几个数据成员,其中三个指针分别指向元素存储区的起始位置、最后一个有效元素之后的位置、内存即总容量的末尾,还会设有一个成员用于分配和释放对象。
完整的vector容器较为庞大,包含构造/析构、赋值、容量管理、元素访问、迭代器、内存管理等一系列操作。鉴于苯人的水平,决定循序渐进,先写一个最小可用的试试看。
主要先实现最基础的push_back与pop_back吧,这里需要注意的是vector的扩容机制,当你push一个元素进入vector时容量已满,它会以倍数的形式进行扩容,一般是2倍,这里苯人想起来push_back和emplace_back的区别但是暂时用不到就先不说了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| #pragma once #include <cstddef> #include <stdexcept> #include <iostream>
namespace kiri {
template<typename T> class vector { public: vector() : data_(nullptr), size_(0), capacity_(0) {}
~vector() { delete[] data_; } void push_back(const T& value) { if (size_ == capacity_) { reserve(capacity_ == 0 ? 1 : capacity_ * 2); } data_[size_++] = value; } void pop_back() { if (size_ > 0) --size_; } T& operator[](std::size_t i) { return data_[i]; } const T& operator[](std::size_t i) const { return data_[i]; } std::size_t size() const { return size_; } std::size_t capacity() const { return capacity_; } void clear() { size_ = 0; }
private: void reserve(std::size_t new_cap) { T* new_data = new T[new_cap]; for (std::size_t i = 0; i < size_; ++i) { new_data[i] = data_[i]; } delete[] data_; data_ = new_data; capacity_ = new_cap; }
private: T* data_; std::size_t size_; std::size_t capacity_; };
}
|
✅ 正确扩容
✅ 存储泛型类型
✅ 支持 push_back/pop_back
✅ 满足绝大多数基本测试
测试代码,结果如下:
