实现C++ STL里面的一个顺序容器vector
如上图所示,vector底层维护的也是一个数组,使用3个指针:
- _first:指向数组的起始位置
- _last:指向数组中有效元素的后继位置
- _end: 指向数组空间的后继位置
不添加空间配置器,简单实现vector容器
#include <iostream>
template<typename T>
class Vector
{
public:
// 构造函数
Vector(int size=10) {
_first = new T[size];
_last = _first;
_end = _first + size;
}
// 析构函数
~Vector() {
delete[]_first;
_first = _last = _end = nullptr;
}
// 拷贝构造函数,进行深拷贝(注意:拷贝构造对象,函数体中当然没有释放当前资源,毕竟对象还没构造,哪来的资源释放)
Vector(const Vector<T>& src) {
int size = src._end - src._first; // 容器容量
int len = src._last - src._first; // 元素个数
_first = new T[size];
for (int i = 0; i < len; ++i) {
_first[i] = src._first[i];
}
_last += len;
_end += size;
}
// 赋值重载函数
Vector<T>& operator=(const Vector<T>& src) {
// 防止自赋值
if (this == &src)
return *this;
// 释放当前对象占用的外部资源
delete[]_first;
// 执行深拷贝
int size = src._end - src._first; // 容器容量
int len = src._last - src._first; // 元素个数
_first = new T[size];
for (int i = 0; i < len; ++i) {
_first[i] = src._first[i];
}
_last += len;
_end += size;
}
// 容器末尾添加元素
void push_back(const T& val) {
if (full())
expand();
*_last = val;
_last++;
}
// 从容器末尾删除元素
void pop_back() {
if (empty())
return;
--_last;
}
// 获取容器末尾元素
T back() const {
return *(_last - 1);
}
// 判满函数
bool full() { return _last == _end; }
// 判空函数
bool empty() { return _first == _last; }
private:
// 二倍扩容函数
void expand() {
int size = _end - _first;
T* ptmp = new T[2 * size];
for (int i = 0; i < size; ++i) {
ptmp[i] = _first[i];
}
delete[]_first;
_first = ptmp;
_last = _first + size;
_end = _first + 2 * size;
}
private:
T* _first; // 指向数组的起始位置
T* _last; // 指向数组中最后一个元素的后继位置
T* _end; // 指向数组空间的后继位置
};
int main() {
Vector<int> vec;
for (int i = 0; i < 20; ++i) {
vec.push_back(rand() % 100 + 1);
}
while (!vec.empty()) {
std::cout << vec.back() << " ";
vec.pop_back();
}
std::cout << std::endl;
return 0;
}