STL vector
作者:
艾西韵
,
2022-02-26 11:47:04
,
所有人可见
,
阅读 249
#include <iostream>
using namespace std;
#define DEFAULT_CAPACITY 10 // 默认容量
template <typename T>
class Vector {
private:
T * _data = nullptr; // 指向T类型元素的指针, 旨在借助动态数组实现Vector
int _size = 0; // 保存元素个数
int _capacity = DEFAULT_CAPACITY; // 容量, 即当前动态数组的大小
public: // 公共接口
explicit Vector(int capacity = DEFAULT_CAPACITY); // 可以指定初始大小
Vector(const Vector<T> & other); // 拷贝构造
Vector(Vector<T> && other); // 移动构造
Vector<T>& operator= (const Vector<T> & other); // 拷贝赋值
Vector<T>& operator= (Vector<T> && other); // 移动赋值
void push_back(const T& ele); // 增
void removeAt(int index); // 删
T& at(int index); // 获取下标为index的元素的引用
const T& at(int index) const; // 上者的const重载
int size() const; // 获取当前元素个数
~Vector();
private: // helper-function(s)
void extend(); // 根据当前元素多少对数组进行扩展
};
template <typename T>
Vector<T>::Vector(int cap) {
_capacity = cap;
_data = new T[cap];
}
template <typename T>
Vector<T>::~Vector() {
if (_data) delete [] _data; // _data != nullptr
}
template <typename T>
void Vector<T>::push_back(const T& ele) {
extend(); // 检查是否需要扩展
_data[_size] = ele; // 加在_data的尾部
++_size; // 更新_size
}
template <typename T>
void Vector<T>::removeAt(int index) {
for (int i = index; i < _size + 1; ++i) {
_data[i] = _data[i + 1]; // 要求T适当的重载了赋值运算符(或原生类型)
}
--_size; // 更新_size
}
template <typename T>
T& Vector<T>::at(int index) {
return _data[index]; // 返回下标为index的值, 无越界检查
}
template <typename T>
const T& Vector<T>::at(int index) const {
return _data[index]; // 返回下标为index的值, 无越界检查
}
template <typename T>
int Vector<T>::size() const {
return _size;
}
// 核心操作
template <typename T>
void Vector<T>::extend() {
if (_size < _capacity) return; // 恰好满载才扩展
_capacity <<= 1; // 两倍扩容
T * oldData = _data; // 保留以赋值即释放原有内存
_data = new T[_capacity]; // 获取翻倍空间
for (int i = 0; i < _size; ++i) { // copy, 不使用memset等操作是因为T可能是含指针的类型
_data[i] = oldData[i];
}
delete [] oldData; // 释放原有内存空间
}
int main() {
Vector<int> v;
for (int i = 0; i < 21; ++i)
v.push_back(i);
for (int i = 0; i < v.size(); ++i)
cout << v.at(i) << ", ";
cout << "\n" << v.size() << "\n";
v.removeAt(17);
for (int i = 0; i < v.size(); ++i)
cout << v.at(i) << ", ";
cout << "\n" << v.size() << "\n";
v.removeAt(5);
for (int i = 0; i < v.size(); ++i)
cout << v.at(i) << ", ";
cout << "\n" << v.size() << "\n";
return 0;
}