数组类模板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