Vector.hpp
#pragma once
#include<cstdlib>
#define SPACE_MAX 16 //表示数组的最小长度
template<class T>
class Vector
{
private:
T* data;//维护动态数组的指针
int size;//数组的数据元素的个数
int max;//当前数组最大能容纳的元素个数
void Error(const char* cs)const { cout << cs << endl; exit(1); }//错误信息报告
public:
//这里的构造函数,里面的形参n,决定了当前数组的长度,但为了防止长度不够用,减少扩容次数,这里会给n+ SPACE_MAX作为数组最大容纳元素个数
explicit Vector(int n = 0) :size(0), max(n + SPACE_MAX),data(NULL)
{
if (max > 0)
data = new T[max];
};
//复制构造函数
Vector(const Vector& v):data(NULL),max(0)
{
//这里用深拷贝---防止堆区内存重复释放
data = new T[v.max];
size = v.size;
max = v.max;
for (int i = 0; i < size; i++)
{
data[i] = v.data[i];
}
}
//析构函数
~Vector()
{
delete[] data;
}
//赋值运算符重载
Vector& operator=(const Vector<T>& v);
//下标运算符重载
T& operator[](int id)
{
return data[id];
}
//常量型下标运算符重载---只有后置const可以作为重载条件,前置不行
const T& operator[](int id)const
{
return data[id];
}
//判断是否为空
bool Empty()const
{
return size == 0;
}
//求当前容器中元素个数
int Size()const
{
return size;
}
//求数组最大的容量
int Max()const
{
return max;
}
//清空数组
void Clear()const
{
size = 0;
}
//迭代器
typedef T* iterator;
//const型迭代器
typedef const T* const_iterator;
//返回开始迭代器
iterator Begin()
{
return data;
}
const_iterator Begin()const
{
return data;
}
//返回结束迭代器
iterator End()
{
return data+size;
}
const_iterator End()const
{
return data + size;
}
//返回首元素的引用
const T& Front()const
{
return data[0];
}
T& Front()
{
return data[0];
}
//返回尾元素的引用
const T& Back()const
{
return data[size - 1];
}
T& Back()
{
return data[size - 1];
}
//尾插
void Push_back(const T& item)
{
data[size++] = item;
}
//尾删
void Pop_back()
{
size--;
}
//扩容函数
void Reserve(int newMax);
//增值函数
void resize(int newSize, const T& item);
//插入函数--插入到指定迭代器之前,返回的迭代器指向新元素所处位置
iterator Insert(iterator itr, const T& item);
//删除函数----删除迭代器指向位置的数据,返回迭代器,但此时迭代器指向的值应该是未删除前位置的后一个位置元素
iterator Erase(iterator itr);
};
//赋值运算符重载
template<class T>
Vector<T>& Vector<T>::operator=(const Vector<T>& v)
{
//先判断两个容器最大值是否相等
if (max != v.max)
{
//深拷贝防止堆区内存重复释放
delete[] data;
max = v.max;
data = new T[max];
}
size = v.size;
for (int i = 0; i < size; i++)
data[i] = v[i];
return *this;
}
//扩容函数
template<class T>
void Vector<T>::Reserve(int newMax)
{
//如果当前newMax比max还小,拿扩了个寂寞,当然直接返回喽!
if (newMax < max) return;
//进行扩容操作--开辟新空间存放原来的数据
//我们要先保留原数组
T* old = data;
data = new T[newMax];
for (int i = 0; i < size; i++)
data[i] = old[i];
//除了新的数组最大容量需要更新,别的不需要
max = newMax;
delete[] old;
}
//增值函数
template<class T>
void Vector<T>::resize(int newSize, const T& item)
{
//如果新增元素个数比最大容量都多,要干嘛?----扩容啊,愣着干嘛呢!
if (newSize > max)
Reserve(newSize * 2 + 1);
//把新增加的元素初始化为item
for (int i = size; i < newSize; i++)
data[i] = item;
size = newSize;
}
//插入函数--插入到指定迭代器之前,返回的迭代器指向新元素所处位置
//这里注意typename---因为
template<class T>
typename Vector<T>::iterator Vector<T>::Insert(iterator itr, const T& item)
{
//容量已满,要先扩容
if (size == max)
{
Reserve(size * 2 + 1);
}
//把要插入位置之后的元素统统后移一位,从数组最后一个元素开始一个个往后移
for (iterator p = data + size, q = data + size - 1; p != itr; --p, --q)
{
//p迭代器在q迭代器之后
//注意原itr位置的元素也要往后移,这就是为什么结束条件是p!=itr
*p = *q;
}
*itr = *item;
size++;
return itr;
}
//删除函数----删除迭代器指向位置的数据,返回迭代器,但此时迭代器指向的值应该是未删除前位置的后一个位置元素
template<class T>
typename Vector<T>::iterator Vector<T>::Erase(iterator itr)
{
//从删除位置开始的后一个元素依次前移一位,直到数组最后一个元素移动后,结束
for (iterator p = itr, q = itr + 1; q != data + size; ++p, ++q)
{
*p = *q;
}
size--;
return itr;
}
main.cpp
#include<iostream>
using namespace std;
#include"Vector.hpp"
template<class iterator>
void display(iterator first,iterator last)
{
for (; first != last; ++first)
{
cout << *first << " ";
}
cout << endl;
}
void test()
{
Vector<int> v;
for (int i = 0; i < 10; i++)
v.Push_back(i);
//这里类型已经确定了,就不用在通过typename来声明类型
Vector<int>::iterator itr = v.Begin();
cout << "after operator++: " << endl;
cout << *(++itr) << endl;
cout << "after operator--" << endl;
cout << *(--itr) << endl;
v.Erase(itr);
cout << "after eraseing the first: " << endl;
display(v.Begin(), v.End());
v.Pop_back();
cout << "after erasing the last: " << endl;
cout << v.Front() << endl;
cout << v.Back() << endl;
Vector<int> v1 = v;
v1.Reserve(20);
v1.resize(20, 5);
cout << "v1.size= " << v1.Size() << endl;
for (int i = 0; i < v1.Size(); ++i)
v1[i]++;
cout << "after reserve(20),resizing(20,5) and adding(1): " << endl;
display(v1.Begin(), v1.End());
cout << "v1.size= " << v1.Size() << endl;
}
int main()
{
test();
return 0;
}
补充:删除[first,last)区间的数据,返回当前数据的位置的erase重载函数。
代码:
template<class T > typename Vector<T>::iterator Vector<T>::Erase(iterator first, iterator last)
{
//计算删除的元素个数
int num = last - first;
//删除指定区间里面的元素
if (last != End())
{
//计算剩余需要移动的元素个数
int leftNum = End() - last;
iterator p = first, q = last;
for (int i = 0; i < leftNum; i++,++p,++q)
{
*p = *q;
}
}
size -= num;
//返回first迭代器之前的一个元素
return first;
}
推荐下面一种写法:
template<class T > typename Vector<T>::iterator Vector<T>::Erase(iterator first, iterator last)
{
iterator p = first;
iterator q = last;
for (; q != data + size; ++p, ++q)
*p = *q;
size -= last - first;
return first;
}
补充:在pos处插入另一个Vector容器指定区间[first, last)的数据的函数
代码:
//在pos处插入另一个Vector容器指定区间[first, last)的数据
template<class T> void Vector<T>::Insert(iterator pos, iterator first, iterator last)
{
//计算需要插入的元素个数
int num = last - first;
if (num + size > max)
Reserve((num + size) * 2);
//先把从pos位置开始的元素后移num个位置
for (iterator p = End(), q = End() + num; p != pos - 1; --p, --q)
*q = *p;
//从pos位置开始,依次插入num个新元素
for (int i = 0; i < num; i++)
*pos++ = *first++;
size += num;
}
补充: 交换两个Vector中的数据—swap函数
代码:
//交换两个Vector中的数据
template<class T>
void Vector<T>::Swap(Vector<T>& v)
{
//交换指针的指向
T* temp = data;
data = v.data;
v.data = temp;
//交换元素个数
int t = size;
size = v.size;
v.size = t;
//交换数组容量
int m = max;
max = v.max;
v.max = m;
}
推荐写法—该写法需注意深拷贝问题:
//交换两个Vector中的数据
template<class T>
void Vector<T>::Swap(Vector<T>& v)
{
Vector<T> temp = *this;
*this = v;
v=temp;
}
注意:
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有