1.动态数组的模板类
#ifndef CARRAY_INCLUDE_H
#define CARRAY_INCLUDE_H
#include <cassert>
template <class T> class CArray{ //数组类模板的定义
private:
T* list; //用于存放动态分配的数组内存首地址
int size; //数组的大小(元素的个数)
public:
CArray(int sz = 50); //构造函数
CArray(const CArray<T> &a); //复制构造函数
~CArray(); //析构函数
CArray<T>& operator=(const CArray<T> &rhs); //重载"="运算符
T& operator[](int i); //重载"[]"下标运算符
const T& operator[](int i)const; //重载“[]”为常函数(只读)
operator T*(); //重载指针运算符
operator const T*()const;
int GetSize() const; //获取数组的大小
void ReSize(int sz); //修改数组的大小
};
/*构造函数*/
template <class T> CArray<T>::CArray(int sz)
{
assert(sz >= 0); //sz为数组大小(元素个数),应当非负
size = sz;
list = new T[size]; //动态分配size个T类型的元素空间
}
/*析构函数*/
template <class T> CArray<T>::~CArray()
{
delete [] list;
}
/*拷贝构造函数*/
template <class T> CArray<T>::CArray(const CArray<T> &a)
{
size = a.size; //从对象x取得数组的大小,并赋值给当前对象的size成员
list = new T[size]; //动态分配a.size个T类型的元素空间
for (int i = 0; i < size; i++)
{
list[i] = a.list[i]; //将对象a的所有元素赋值到本对象
}
}
/*重载“=”运算符,将对象rhs赋值给本对象,实现整体赋值*/
template < class T>CArray<T> &CArray<T>::operator=(const CArray<T>& rhs)
{
if (&rhs != this)
{
if (size != rhs.size) //如果对象中数组大小与rhs不同,则删除数组原有内存,然后重新分配
{
delete[] list; //设置本对象的数组大小
size = rhs.size; //设置本对象的数组大小
list = new T[size]; //重新分配size大小的数组空间
}
for (int i = 0; i < size; i++)
{
list[i] = rhs.list[i]; //将数组rhs中的元素依次复制到本对象中
}
}
return *this; //返回当前对象的引用
}
/*重载“[]”下标运算符,实现与普通数组一样可通过下标访问元素,并且具有越界检查功能*/
template < class T> T& CArray<T>::operator[](int n)
{
assert(n >= 0 && n < size); //检查数组下标是否越界
return list[n]; //返回下标n的数组元素
}
/*重载下标运算符[]*/
template <class T>const T& CArray<T>::operator[](int n)const
{
assert(n >= 0 && n < size); //检查数组下标是否越界
return list[n]; //返回下标为n的数组元素
}
/*重载指针转换运算符*,将CArray类的对象名转换为T类型的指针*/
template <class T>CArray<T>::operator T*()
{
return list; //返回当前对象中私有数组的首地址
}
/*重载指针转换运算符**/
/*template <class T>const CArray<T>::operator T*()const
{
return list;
}*/
/*获取当前数组的大小*/
template <class T> int CArray<T>::GetSize()const
{
return size;
}
/*将数组大小修改为sz*/
template <class T>void CArray<T>::ReSize(int sz)
{
assert(sz >= 0); //检查sz是否为0
if (sz == szie) //如果指定的大小与原有数组大小相同,则什么也不做,返回
return;
T* newList = new T[sz]; //动态分配新数组,大小为sz
int n = (sz < size) ? sz : size; //n取sz和size中较小值
for (int i = 0; i < n; i++)
{
newList[i] = list[i]; //将原有数组list中的n个值复制到新数组中
}
delete[] list; //删除原有数组
list = newList; //使list指向新数组
size = sz; //更新size的值
}
#endif
测试代码:
#include <iostream>
#include "CArray.h"
using namespace std;
void read(int *p, int n); //如果没有指针转换运算符,该函数将失效
void read(int *p, int n)
{
for (int i = 0; i < n; i++)
cin >> p[i];
}
int main()
{
CArray<int> a(10);
read(a, 10);
cout << a[5] << endl;
return 0;
}
运行结果如图:
2.求范围2~N中的质数,N在程序运行时由键盘输入。
测试代码:
#include <iostream>
#include <iomanip>
#include "CArray.h"
using namespace std;
int main()
{
CArray<int> a(10); //用来存放质数的数组,初始状态有十个元素
int n, count = 0;
cout << "Enter a value >= 2 as upper limit for prime number: ";
cin >> n;
//检查i是否能被比它小的质数整除
for (int i = 2; i <= n; i++)
{
bool isPrime = true;
for (int j = 0; j < count; j++)
{
//若i被a[j]整除,说明i不是质数
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;
}
测试用例:
来自清华大学MOOC课件