?? 9_3.h
字號:
//9-3.h
#ifndef ARRAY_CLASS
#define ARRAY_CLASS
#include <iostream>
#include <cstdlib>
#ifndef NULL
const int NULL = 0;
#endif // NULL
//錯誤類型集合,共有三種類型的錯誤:數組大小錯誤、內存分配錯誤和下標越界
enum ErrorType
{invalidArraySize, memoryAllocationError, indexOutOfRange};
//錯誤信息
char *errorMsg[] =
{
"Invalid array size", "Memory allocation error",
"Invalid index: "
};
//數組類模板聲明
template <class T>
class Array
{
private:
T* alist; //T類型指針,用于存放動態分配的數組內存首地址
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); //重載"="使數組對象可以整體賦值
T& operator[](int i); //重載"[]",使Array對象可以起到C++普通數組的作用
operator T* (void) const; //重載T*,使Array對象可以起到C++普通數組的作用
int ListSize(void) const; // 取數組的大小
void Resize(int sz); // 修改數組的大小
};
//以下為類成員函數的定義
//模扳函數Error實現輸出錯誤信息的功能
template <class T>
void Array<T>::Error(ErrorType error, int badIndex) const
{
//由于頭文件有可能被許多其它源程序文件包含,因此不以將std名名空間中的全部
//標識符引入當前命名空間,也就是說不宜使用"using namespace std;"。
//為了使用std命名空間中的標識符,如cout,這里使用了"std::"
std::cout << errorMsg[error]; //根據錯誤類型,輸出相應的錯誤信息
if (error == indexOutOfRange)
std::cout << badIndex; //如果是下標越界錯,輸出錯誤的下標
std::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是本對象中的數組首地址
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)
{
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; // 將sz與size中較小的一個賦值給n
// 將原有數組中前n個元素復制到新數組中
T* srcptr = alist; // 原數組alist的首地址
T* destptr = newlist; // 新數組newlist的首地址
while (n--) // 復制數組元素
*destptr++ = *srcptr++;
delete[] alist; // 刪除原數組
alist = newlist; // 使alist 指向新數組
size = sz; // 更新size
}
#endif // ARRAY_CLASS
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -