1、动态数组类模版
例:动态数组模版class ARRAY_CLASS
#include <iostream.h>
#include<stdlib.h>
#ifndef ARRAY_CLASS
#define ARRAY_CLASS
const int NULL=0;
enum ErrorType//枚举类型ErrorType
{invalidArraySize,memoryAllocationError,indexOutOfRange};
//指针数组,三个指针分别指向三个字符串
char *errorMsg[]={"Invalid arry size","Memorry allocation error,""Invalid index:"};
template<class T>
class Array
{
T *alist;
int size; //数组大小
//常成员函数,enum型error,出错脚标badIndex默认0,作用是输出错误类型。
void Error(ErrorType error,int badIndex=0) const;
public:
//构造函数,数组初始范围为50,作用是确定数组范围,为数组申请空间
Array(int sz=50);
Array(const Array<T>& A);//拷贝构造函数
~Array(void); //析构函数
//运算符重载,将已存在的两个,进行赋值。
Array<T>& operator=(const Array<T>& rhs);
//重载下标操作符,实现与普通数组一样通过下表访问元素,并且具有越界检查
T& operator[](int i);
operator T*(void) const;//指针重载
int ListSize(void) const;
void Resize(int sz);//改变数组大小
};
template<class T> //Error函数,输出错误类型
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; //将元素个数赋值给变量size
alist=new T[size]; //动态分配size个T型的元素空间
if(alist==NULL)//如果分配内存不成功,输出错误信息
Error(memoryAllocationError);
}
template<class T> //析构函数,释放为数组申请的空间。
Array<T>::~Array(void)
{delete[]alist;}
/*浅拷贝,是不行的,当Array两个对象指针指向同一区域,
array两个对象A和B,之后进行析构,将A析构后B析构时将会发生错误,
因为A和B地址指向同一个申请的空间。
template<class T>
Array<T>::Array(const Array<T>& X)
{
size=X.size;
alist=X.alist;
}
void main()
{
Array<int>A(10);
Array<int>B(A);
}*/
template<class T> //深拷贝,令开辟空间,进行数组拷贝
Array<T>::Array(const Array<T>& X)
{
int n=X.size;//从对象X取得数组大小
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* destptr=alist;
T* srcptr=rhs.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的数组元素
}
/*重载指针转换操作符,将Array类对象名转换为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)
{
//检查是否sz<=0
if(sz<=0)
Error(invalidArraySize);
//如果指定的大小与原有大小一样,什么也不做
if(sz==size) return;
//申请新的数组内存,并测试是否申请成功
T* newlist=new T[sz];
if(newlist==NULL)
Error(memoryAllocationError);
//将sz与size中娇小的一个赋值给n
int n=(sz<=size)? sz:size;
//将原有数组中前n个元素复制到新数组中
T* destptr=newlist//新数组newlist的首地址
T* srcptr=alist;//原数组alist的首地址
while(n--) //复制数组元素
*destptr++=*srcptr++;
delete[]alist;//删除原数组
//使alist指向新数组,并更新size
alist=newlist;
size=sz;
}
#endif
例:求范围2-N中的质数,N在程序运行时由键盘输入。
#include<iostream.h>
#include<iomanip.h>
#include"ARRAY.h"
void main()
{
Array<int> A(10);
int n;
int primecount=0,1,j;
cout<<"输入值>=2的求质数数列最大值:\n";
cin>>n;
A[primecount++]=2;//调用运算符重载函数operator[]
for(i=3,i<n;i++)
{
if(primecount==A.ListSize())
A.Resize(primecount+10);
if(i%2==0) continue;
j=3;
while(j<=2&&i%j!=0)
j+=2;
if(j>i/2)
A[primecount++]=i;
}
for(i=0;i<primecout;i++)
{
cout<<setw(5)<<A[i];
if((i+1)%10=0)
cout<<endl;
}
cout<<endl;
}