vector模板类是一种动态数组,支持设置长度、末尾添加数据、中间插入数据等操作,管理内存的方式是通过new/delete动态申请释放,本文重新实现一个Vector模板类,包含简单的默认构造、拷贝构造、析构、重新申请内存以及末尾添加元素等功能。
1. 默认构造,数组长度为0,容器容量为一个规定的默认值,并为数组申请内存。
//构造
Vector() : m_size(0), m_capacity(SPACING) {
m_data = new T[m_capacity];
}
2.填充构造,用size个值初始化数组。
Vector(int size, const T value) : m_size(size), m_capacity(size + SPACING) {
m_data = new T[m_capacity];
for (int i = 0; i < m_size; i++) {
m_data[i] = value;
}
}
3.拷贝构造,注意赋值之前进行一次判断。
Vector(const Vector<T> &other) {
if (!other.m_data) {
m_size = 0;
m_capacity = SPACING;
m_data = new T[m_capacity];
} else {
m_size = other.m_size;
m_capacity = other.m_capacity;
m_data = new Vector[m_capacity];
for (int i = 0; i < m_size; i++) {
m_data[i] = other.m_data[i];
}
}
}
4.重新分配内存(容量扩展到原来的2倍),这个类方法是在添加或插入元素的时候自动调用的。
void resize() {
m_capacity *= 2; //扩展空间
T *tmp = m_data;
m_data = new T[m_capacity];
for (int i = 0; i < m_size; i++) {
m_data[i] = tmp[i];
}
delete[] tmp;
}
5.末尾添加元素,最重要的一点是注意判断容器是否已满,如果已满则重新分配内存。
void push_back(const T value) {
if (m_size == m_capacity) {
resize();
}
cout << "size = " << m_size << ", capacity = " << m_capacity << endl;
m_data[m_size++] = value;
}
6.重写下标操作符。
T operator[](int index) {
return m_data[index];
}
类模板Vector的定义
namespace Vec{
#define SPACING 8
typedef size_t size_type;
//默认构造,赋值构造,析构,重置,插入
template <class T>
class Vector {
public:
public:
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
public:
//构造
Vector() : m_size(0), m_capacity(SPACING) {
m_data = new value_type[m_capacity];
}
Vector(size_type size, const value_type value) : m_size(size), m_capacity(size + SPACING) {
m_data = new value_type[m_capacity];
for (size_type i = 0; i < m_size; i++) {
m_data[i] = value;
}
}
Vector(const Vector<value_type> &other) {
if (!other.m_data) {
m_size = 0;
m_capacity = SPACING;
m_data = new value_type[m_capacity];
} else {
m_size = other.m_size;
m_capacity = other.m_capacity;
m_data = new Vector[m_capacity];
for (int i = 0; i < m_size; i++) {
m_data[i] = other.m_data[i];
}
}
}
virtual ~Vector() {
if (m_data) {
delete[] m_data;
m_data = nullptr;
}
}
void push_back(const value_type value) {
if (m_size == m_capacity) {
resize();
}
// cout << "size = " << m_size << ", capacity = " << m_capacity << endl;
m_data[m_size++] = value;
}
value_type pop() {
value_type ret = m_data[m_size - 1];
m_size -= 1;
return ret;
}
value_type operator[](size_type index) { return m_data[index]; }
//带边界检查
value_type at(size_type index) {
if (index > m_size)
throw "out_range";
return m_data[index];
}
value_type back() { return m_data[m_size - 1]; }
value_type font() { return m_data[0]; }
iterator begin() { return m_data; }
iterator end() { return m_data + m_size; }
Vector<value_type> &operator=(const Vector<value_type> &vector) {
if (!vector.m_data) {
m_size = 0;
m_capacity = SPACING;
m_data = new value_type[m_capacity];
} else {
m_size = vector.m_size;
m_capacity = vector.m_capacity;
m_data = new Vector[m_capacity];
for (int i = 0; i < m_size; i++)
m_data[i] = vector.m_data[i];
}
}
size_type size() { return m_size; }
size_type capacity() { return m_capacity; }
void resize(size_type capacity) {
m_capacity = capacity; //扩展容量
value_type *tmp = m_data;
m_data = new value_type[m_capacity];
for (size_type i = 0; i < m_size; i++) {
m_data[i] = tmp[i];
}
delete[] tmp;
}
bool empty() { return !m_size; }
//替换容器内容
void assign(size_type size, const value_type value) {
if (size >= m_capacity)
resize(size + SPACING); //扩展容量
m_size = size;
for (size_type i = 0; i < m_size; i++) {
m_data[i] = value;
}
}
//清空数组
void clear() {
m_size = 0;
m_capacity = m_size + SPACING;
delete [] m_data;
m_data = new value_type[m_capacity];
}
//删除元素
iterator erase(iterator it) {
iterator itx = it;
while (itx != end())
{
*itx = *(itx + 1);
itx++;
}
m_size -= 1;
return it;
}
//删除元素
iterator erase(iterator first, iterator last) {
size_type range = last - first;
iterator itx = first;
while (itx != end())
{
*itx = *(itx + range);
itx++;
}
m_size -= range;
return first;
}
private:
void resize() {
m_capacity *= 2; //自动扩展容量
value_type *tmp = m_data;
m_data = new value_type[m_capacity];
for (size_type i = 0; i < m_size; i++) {
m_data[i] = tmp[i];
}
delete[] tmp;
}
private:
value_type *m_data;
size_type m_size; //大小
size_type m_capacity; //容量
};
}; //namespace Vec
测试代码
int main() {
using namespace Vec;
Vector<int> vector; //创建模板类
vector.push_back(11);
vector.push_back(12);
vector.push_back(13);
vector.push_back(14);
vector.push_back(15);
vector.push_back(16);
vector.push_back(17);
for (size_type i = 0; i < vector.size(); i++)
cout << "vector[" << i << "] = " << vector[i] << " ";
cout << '\n';
cout << "第一个: " << vector.font() << endl;
cout << "最后一个: " << vector.back() << endl;
cout << "删除末尾: " << vector.pop() << endl;
cout << "最后一个: " << vector.back() << endl;
cout << "浮点\n";
Vector<double> vd(6, 12.55); //创建模板类
for (size_type i = 0; i < vd.size(); i++)
cout << "vd[" << i << "] = " << vd[i] << " ";
cout << '\n';
cout << "重新赋值: \n";
vd.assign(10, 3.5);
for (size_type i = 0; i < vd.size(); i++)
cout << "vd[" << i << "] = " << vd[i] << " ";
cout << "\n使用迭代器遍历:\n";
Vector<double>::iterator it = vd.begin();
size_type i = 0;
while (it != vd.end()) {
cout << "vd[" << i << "] = " << *it << " ";
++i;
++it;
}
cout << '\n';
Vector<int> vi;
for (int i = 1; i <= 10; i++)
vi.push_back(i);
vi.erase(vi.begin() + 5);
vi.erase(vi.begin(), vi.begin() + 3);
cout << "\n删除元素处理后:";
for (size_type i = 0; i < vi.size(); ++i)
std::cout << ' ' << vi[i];
cout << '\n';
vi.clear();
for (size_type i = 0; i < 200; i++) {
vi.push_back(i);
}
cout << endl << "size: " << vi.size();
cout << endl << "capacity: " << vi.capacity() << endl;
vi.clear();
cout << "清空以后: ";
cout << endl << "size: " << vi.size();
cout << endl << "capacity: " << vi.capacity() << endl;
vi.push_back(1);
vi.push_back(2);
vi.push_back(3);
vi.push_back(4);
vi.push_back(3);
for (size_type i = 0; i < vi.size(); i++)
{
cout << vi[i] << " ";
}
cout << endl << "删除元素3: " << endl;
Vector<int>::iterator it2 = vi.begin();
while (it2 != vi.end()) {
if (*it2 == 3) {
it2 = vi.erase(it2);
} else {
it2++;
}
}
for (size_type i = 0; i < vi.size(); i++)
{
cout << vi[i] << " ";
}
cout << '\n';
system("pause");
return 0;
}
测试结果