C++动态数组类模板

C和C++学了很久,终于快把基础语法学完了,之后就要进行数据结构和算法的学习,之前写的程序,都是从书上抄下来的,而且很多都是针对着某一个特定的语法,就感觉没有写到博客的必要了,现在学习到了群体类这一块,学着书上写了一个动态数类模板,参考《C++语言程序设计》第266页,代码被详细注释了,感觉用上了之前学过的很多东西,记下来有空了好好在学习学习。

#ifndef ARRAY_CLASS
#define ARRAY_CLASS

#include<iostream> 
#include<stdlib.h>

#ifndef NULL
const int NULL = 0;
#endif//NULL

using namespace std;

enum ErrorType
{
	invalidArraySize, memoryAllocationError, indexOutOfRange
};
//枚举错误信息

char *errorMsg[] = 
{
	"Invalid array size", "Memory allocation error", "Invalid index:"
};

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

//Array.h中的函数实现
//#include"Array.h" 
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;												//将元素个数赋给变量size
	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是本对象中的数组首地址 
 }
 
//重载“=”运算符,将对象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); 
	//返回下标为n的数组元素
	return alist[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* srcptr = alist;				//原数组alist的首地址
	T* destptr = newlist;			//新数组newlist的首地址
	while(n--)
		*destptr ++ = *srcptr ++;
	//删除原数组
	delete[] alist;
	//使alist指向新数组,并更新size;
	alist = newlist;
	size = sz; 
 }
 
#endif//ARRAY.CLASS 

这是Array.h头文件部分,把模板类和其实现都放在了头文件中。

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

using namespace std;

int main(void)
{
	//用来存放质素的数组,初始状态有10个元素
	Array<int> A(10);
	int n;			//质数范围的上限,运行时输入
	int primecount = 0, 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;
		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<<"  "<<A[i];
		//每输出10个数换行一次
		if((i + 1) % 10 == 0)
			cout << endl; 
	}
	cout << endl;
}

这是主程序部分,实现了输入一个数,可以输出小于它的所有质数。


猜你喜欢

转载自blog.csdn.net/weixin_41108706/article/details/79749889