通过重载操作符和模板来封转一个可以自动扩容的数组。
template<typename T>
class CDynamicArray {
public:
T* m_parr;//指向堆区数组的指针
int m_size;//当前有效长度
int m_capacity;//最大容量
explicit CDynamicArray(int len) :m_size(0), m_capacity(len), m_parr(nullptr) {
if(len>0) m_parr = new T[len];//根据给的长度在堆区申请数组
}
explicit CDynamicArray(const CDynamicArray& arr) :m_size(arr.m_size), m_capacity(arr.m_capacity), m_parr(nullptr) {
//判断被cv的那个对象的指针是否为空
if (arr.m_parr) {//不为空
m_parr = new T[m_capacity];//申请和他一样大小的空间
for (int i = 0; i < m_capacity; i++) {//依次拷贝
m_parr[i] = arr.m_parr[i];
}
}
}
CDynamicArray& operator=(CDynamicArray& arr) {//操作符重载 =
if (&arr != this) {//如果不是自己
if (m_parr) {//自己的指针不是空就回收空间
delete[] m_parr;
m_parr = nullptr;
}
m_size = arr.m_size;//把大小都赋值过来
m_capacity = arr.m_capacity;
if (arr.m_parr) {//如果被cv的那个对象的指针不为空
m_parr = new T[m_capacity];//申请一样大小的空间
for (int i = 0; i < m_capacity; i++) {//依次拷贝
m_parr[i] = arr.m_parr[i];
}
}
}
return *this;
}
void PushBack(T& t) {//尾添加
//如果当前的长度在最大容量内
if (m_size < m_capacity) {
//正常尾添加,m_size保存的是数组的当前长度,也是新来的元素应该插入的下标
m_parr[m_size++] = t;
}
else {//不在则扩容1.5倍
int oldSize = m_size++;
m_capacity = m_size < (oldSize + oldSize / 2) ? (oldSize + oldSize / 2) : m_size;
T* tmp = new T[m_capacity];//申请新的空间
for (int i = 0; i < oldSize; i++) {//把原来的数据依次拷贝进去
tmp[i] = m_parr[i];
}
tmp[oldSize] = t;//把新元素插入
delete m_parr;//回收原来的数组空间
m_parr = tmp;//新申请的数组成为对象的数组
tmp = nullptr;
}
}
void PopBack() {//尾删除
//逻辑删除,直接让当前长度-1,下次来新的元素就给他覆盖了
if(m_size>0) m_size--;
}
T& operator[](int index) {//操作符重载 []
if (index < 0 || index >= m_size) {//大于等于当前长度,或小于0的下标是非法下标
cout << "index is invalid" << endl;
}
else {
return m_parr[index];//根据给的下标返回值
}
}
int getLength() {//获取当前长度
return m_size;
}
int getCapacity() {//获取最大容量
return m_capacity;
}
void showArr() {//遍历数组
for (int i = 0; i < m_size; i++) {
cout << m_parr[i] << " ";
}
cout << endl;
}
//有了begin和end就支持范围for遍历
T* begin() {
return m_parr[0];//返回第一个元素
}
T* end() {
return m_parr[m_size];//返回最后一个元素的下一个
}
};
测试
int main() {
CDynamicArray<int> arr(5);
int a = 1;
arr.PushBack(a);
a = 2;
arr.PushBack(a);
a = 3;
arr.PushBack(a);
a = 4;
arr.PushBack(a);
a = 5;
arr.PushBack(a);
a = 6;
arr.PushBack(a);
cout <<arr.getLength()<<" "<<arr.getCapacity()<<" "<<arr[1]<<endl;//6 7 2
arr.showArr();//1 2 3 4 5 6
arr.PopBack();
arr.PopBack();
arr.PopBack();
arr.showArr();//1 2 3
CDynamicArray<int> arr2(6);
arr2 = arr;
cout <<arr2.getLength()<<" "<<arr2.getCapacity()<<" "<<arr2[1]<<endl;//3 7 2
arr2.showArr();//1 2 3
return 0;
}