C++写动态数组

以下是我用C++写的能够实现纠错(数组大小错误,内存分配错误,下标越界)的动态数组,并利用此完成了求素数的任务。因是初学者,注释较多,望高手指正!

//数组类.h
#ifndef ARRAY_CLASS
#define ARRAY_CLASS

#include <iostream>
#include <cstdlib>
using namespace std;

#ifndef NULL             
const int NULL=0;
#endif

//错误类型集合:数组大小错误,内存分配错误,下标越界
enum ErrorType
{invalidArraySize,memoryAllocationError,indexOutOfRange};

//错误信息
char *errorMsg[]={"Invalid Array Size","Memory Allocation Error","Index Out Of Range"};

//数组类模板声明
template <class T>
class Array
{
    private:
        T* alist;     //T类型指针,用于存放动态分配的数组内存首地址
        int size;     //数组大小(元素个数)
        void Error(ErrorType error,int badIndex=0) const;  //错误处理函数
    public:
        Array(int sz=0);    //构造函数
        Array(const Array<T>&A);  //拷贝构造函数
        ~Array (void);         //析构函数
        Array<T>& operator =(const Array<T>& rhs);   //重载“=”使数组对象可以整体赋值
        T& operator[](int i);    //重载“[]”,使Array对象可以起到C++普通数组的作用
        operator T*(void) const;    //重载“*”,使Array对象可以起到C++普通数组的作用
        int ListSize(void) const;   //取数组的大小
        void Resize(int sz);        //修改数组的大小
};

//以下为类成员函数的定义
//模板函数Error实现输出错误信息的功能
template <class T>
void Array<T>::Error(ErrorType error,int badIndex) const
{
    cout<<errorMsg[error];   //根据错误类型,输出相应的错误信息
    if(error==indexOutOfRange)
        cout<< badIndex;     //如果是下标越界错误,输出错误的下标
    cout<<endl;
    exit(1);
}

//构造函数
template <class T>
Array<T>::Array(int sz)
{
    if(sz<=0)                //sz为数组的大小,若小于0,则输出错误信息
        Error(invalidArraySize);
    size=sz;
    alist=new T[size];       //动态分配size个T类型的元素空间
    if(alist==NULL)          //如果分配内存不成功,输出错误信息
        Error(memoryAllocationError);
}

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

//拷贝构造函数
template<class T>
Array<T>::Array(const Array<T>& X)  //深拷贝
{
    //对对象X取得数组大小,并赋值给当前对象的成员
    int n=X.size;
    size=n;
    //为对象申请内存并进行出错检查
    alist=new T[n];    //动态分配n个T类型的元素空间
    if (alist==NULL)   //如果分配内存不成功,输出错误信息
        Error(memoryAllocationError);
    //从对象X赋值数组元素到本对象
    T* srcptr=X.alist;   //X.alist是对象X的数组首地址
    T* destptr=alist;    //alist是本对象中的数组首地址
    while(n--)           //逐个赋值数组元素
        * destptr++=* srcptr++;
}

//重载“=”,将对象rhs赋值给本对象,实现对象之间的整体赋值
template<class T>
Array<T>&Array<T>::operator =(const Array<T>& rhs)
{
    int n=rhs.size;  //取rhs数组大小
    //如果本对象中数组大小与rhs的不同,则删除原来内存,然后重新分配
    if(size!=n)
    {
        delete[] alist;     //删除原来的内存
        alist= new T[n];    //重新分配n个元素的内存
        if(alist==NULL)     //如果分配内存不成功,输出错误信息
            Error(memoryAllocationError);
        size=n;             //记录本对象的数组大小
    }
    //从rhs向本对象复制元素
    T* srcptr=rhs.alist;   
    T* destptr=alist;    
    while(n--)           
        * destptr++=* srcptr++;
    return *this;   //记录当前对象的引用
}

//重载下标[]运算符,实现与普通数组一样通过下标访问元素,并且具有越界检查功能
template<class T>
T& Array<T>::operator[](int n)
{
    if(n<0||n>size-1)  //检查下标是否越界
        Error(indexOutOfRange,n);
    return alist[n];  //返回下标为n的数组元素
}

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

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

//将数组大小修改为sz
template<class T>
void Array<T>::Resize(int sz)
{
    if(sz<=0)                  //检查是否sz<=0
        Error(invalidArraySize);
    if(sz==size)              //如果指定的大小与原有大小一样,什么也不做
        return;
    T* newlist=new T[sz];     //申请新的数组内存
    if(newlist==NULL)         //测试新的数组内存是否申请成功
        Error(memoryAllocationError);
    int n=(sz<=size)?sz:size;  //将size与sz中较小的赋值给n
    //将原有数组中前n个元素的复制到新数组中
    T* srcptr=alist;   
    T* destptr=newlist;   
    while(n--)           
        * destptr++=* srcptr++;
    delete[] alist;     //删除原数组
    alist=newlist;      //使alist指向新数组
    size=sz;            //更新size
}
#endif

//动态数组.cpp
#include<iostream>
#include<iomanip>
#include"数组类.h"
using namespace std;

int main()
{
    Array<int> A(10);    //用来存放质数的数组,初始状态有十个元素
    int n;               //质数范围的上限
    int primecount=0;   
    int i,j;

    cout<<"Enter a value >=2 as upper limit for prime numbers:";
    cin>>n;

    A[primecount++]=2;      //2是一个质数
    for(i=3;i<n;i++)
    {
        //如果质数表满了,再申请分配10个元素的空间
        if(primecount==A.ListSize())
            A.Resize(primecount+10);
        //大于2的偶数不是质数,因此略过本次循环的后继部分,进入下一次循环
        if(i%2==0)
            continue;
        //检查3,5,7……是否为i的因子
        j=3;
        while(j<=i/2&&i%j!=0)
            j+=2;
        //若上述参数都不是i的因子,则i是质数
        if(j>i/2)
            A[primecount++]=i;
    }

    for(i=0;i<primecount;i++)    //输出质数
    {
        cout<<setw(5)<<A[i];
        if((i+1)%10==0)         //每输出10个数换行一次
            cout<<endl;
    }
    cout<<endl;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值