C++模板类封装数组

 通过重载操作符模板来封转一个可以自动扩容的数组。

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;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值