直接访问群体——动态数组类

数组类模板Array弥补了静态数组的不足,其大小可变,且具有边界检查功能,可以捕捉非法的数组下标。由于对下标运算符“[]”和指针转换运算符“T*”进行了重载,使得Array类的对象可以像普通数组一样使用。

数组类模板

    静态数组是具有固定元素个数的群体,其中的元素可以通过下标直接访问。

        缺点:大小在编译时就已经确定,在运行时无法修改。

    动态数组由一系列位置连续的,任意数量相同类型的元素组成。

        优点:其元素个数可在程序运行时改变。

    vector就是用类模板实现的动态数组。

【数组类实现】

//Array.h

#ifndef ARRAY_ARRAY_H
#define ARRAY_ARRAY_H
#include <cassert>

//数组类模板定义
template<class T>
class Array {
private:
    T *list; //T型指针,用于存放动态分配的数组内存首地址
    int size;
public:
    Array(int sz = 50); //构造函数
    Array(const Array<T> &a); //复制构造函数
    ~Array();  //析构函数
    Array<T> & operator = (const Array<T> &rhs); //重载“=”使数组能整体赋值
    T & operator [] (int i); //重载“[]“使得Array可以起到普通数组的作用
    const T & operator [] (int i) const;  //”[]“对const重载
    operator T* ();  //重载指针转换符,将Array类的对象名转换为T类型的指针
    operator const T* () const;
    int getSize() const;  //取数组的大小
    void resize(int sz);  //修改数组大小
};

//构造函数
template<class T>
Array<T>::Array(int sz) {
    assert(sz >= 0);  //检查数组大小是否大于零,若否则报错
    size = sz;
    list = new T [size];  //动态分配size个元素的内存
}

//析构函数
template<class T>
Array<T>::~Array() {
    delete [] list;
}

//复制构造函数
template<class T>
Array<T>::Array(const Array<T> &a) {
    size = a.size;  //对当前对象大小赋值
    list = new T [size];
    for (int i = 0; i < size; i++) {
        list[i] = a.list[i];
    }
}

//重载“=”使数组能整体赋值
template<class T>
Array<T> &Array<T>::operator=(const Array<T> &rhs) {
    if (&rhs != this) {
        //如果本对象中数组大小与rhs不同则删除原有内存重新分配
        if (size != rhs.size) {
            delete [] list;
            size = rhs.size;
            list = new T [size];
        }
        for (int i = 0; i < size; i++) {
            list[i] = rhs.list[i];
        }
    }
    return *this;
}

//重载下标运算符,实现通过下标访问元素和越界审查功能
template<class T>
T &Array<T>::operator[](int i) {
    assert(i >= 0 && i < size);  //检查下标是否越界;
    return list[i];  //返回下标为i的数组元素
}

template<class T>
const T &Array<T>::operator[](int i) const {
    assert(i >= 0 && i < size);  //检查下标是否越界;
    return list[i];  //返回下标为i的数组元素
}

//重载指针转换符,将Array类的对象名转换为T类型的指针,
//指向当前对象中的私有数组,
//因而可以像使用普通数组首地址一样使用Array类的对象名
template<class T>
Array<T>::operator T *() {
    return list;
}

template<class T>
Array<T>::operator const T *() const {
    return list;
}

//取当前数组大小
template<class T>
int Array<T>::getSize() const {
    return size;
}

template<class T>
void Array<T>::resize(int sz) {
    assert(sz >= 0);
    if (sz == size) {
        return;
    }
    T *newList = new T [sz];
    int n = (sz > size) ? sz : size;  //将两者中较小值赋给n
    for (int i = 0; i < n; i++) {
        newList[i] = list[i];
    }
    delete [] list;   //删除原数组
    list = newList;   //使list指向新数组
    size = sz;   //更新size
}

#endif //ARRAY_ARRAY_H

【测试用主函数】

#include <iostream>
#include <iomanip>
#include "Array.h"

using namespace std;

int main() {
    Array<int> a(10);
    int count = 0;

    int n;
    cout << "Enter the upper limit: " ;
    cin >> n;


    for(int i = 2; i <= n; i++) {
        bool isPrime = true;
        for (int j = 0; j < count; j++) {
            if (i % a[j] == 0) {
                isPrime = false;
                break;
            }
        }
        if (isPrime) {
            if (count == a.getSize()) {
                //若质数表满了,则将其空间加倍
                a.resize(count * 2);
            }
            a[count++] = i;
        }
    }

    for (int i = 0; i < count; i++) {
        cout << setw(8) << a[i];
    }
    cout << endl;

    return 0;
}

【示例结果】

Enter the upper limit: 100
       2       3       5       7      11      13      17      19      23      29      31      37      41      43      47      53      59      61      67      71      73      79      83      89      97

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

*OASIS*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值