1 相关概念
- 动态数组:在数组中插入元素时,如果数组容量已满,则进行扩容(类的void extend()私有函数),扩为原来的两倍。
- 自己定义异常类:创建多个构造函数。在测试案例中,利用try…catch捕获异常。
- 构造函数、析构函数和拷贝构造函数
- 操作符[]、<<(不能重载到成员函数中)重载。
目前案例比较简单,插入和删除都在数组的尾部进行。如果在前段和中部插入和删除就要涉及其他元素的移动,但也比较容易实现(可利用copy函数实现)。
2 相应的代码
- 异常类代码
// "OutofRange.h"
#ifndef _OUTOFRANGE_H
#define _OUTOFRANGE_H
#include<iostream>
class OutofRange
{
public:
OutofRange() :err_t(1) {}
OutofRange(int _arrcapacity,int _arrsize,int _arrindex) :arrcapacity(_arrcapacity),
arrsize(_arrsize),arrindex(_arrindex),err_t(2){}
//~OutofRange() {} //没有指针,不用自己定义析构函数。
//方法
void what() const;
private:
int err_t; //错误类型
int arrindex; //元素所在的索引
int arrsize;
int arrcapacity; //数组的容量
};
void OutofRange::what()const
{
if (err_t == 1)
{
std::cout << "当前数组为空!";
}
else if (err_t == 2)
{
std::cout << "当前元素所在的索引:" << arrindex
<< ",当前数组元素的个数: " << arrsize
<< ",当前数组的容量:" << arrcapacity;
}
else
{
std::cout << "其他未知错误。";
}
}
#endif // !_OUTOFRANGE_H
- 动态数组代码
#ifndef ARRRAY_H
#define ARRAY_H
#include"OutofRange.h"
#include<iostream>
template<class T>
class Array
{
template<class T>
friend std::ostream& operator<<(std::ostream&, const Array<T>&);
public:
Array(int initalcapacity = 10);
Array(const Array<T>&);
~Array() { delete[]element; }
//ADT方法
bool empty() { return arrsize == 0; }
int getsize()const { return arrsize; }
void push(const T &theElement);
void pop();
T& operator[](int i) const; //重载[]操作符,获取数组元素。
void clear();
private:
T* element;
int arrsize;
int arrcapacity ;
void extend();
};
template<class T>
void Array<T>::clear()
{
for (int i = arrsize - 1; i >= 0; i--)
{
element[i].~T();
--arrsize;
}
;
}
//拷贝构造函数
template<class T>
Array<T>::Array(const Array<T>& arr)
{
arrsize = arr.arrsize;
arrcapacity = arr.arrcapacity;
element = new T[arrcapacity];
std::copy(arr.element, arr.element + arrsize, element);
}
//构造函数
template<class T>
Array<T>::Array(int initalcapacity)
{
arrcapacity = initalcapacity;
arrsize = 0;
element = new T[arrcapacity];
}
//操作符<<重载
template<class T>
inline
std::ostream& operator<<(std::ostream& out, const Array<T>& arr)
{
for (int i=0;i<arr.arrsize;i++)
out << *(arr.element+i) << " ";
out << std::endl;
return out;
}
//操作符[]重载
template<class T>
T& Array<T>::operator[](int i) const
{
if (i > arrsize - 1 || i < 0) throw OutofRange(arrcapacity, arrsize, i);
return *(element + i);
}
//尾端删除一个元素
template<class T>
void Array<T>::pop()
{
if (arrsize == 0) throw OutofRange();
element[arrsize - 1].~T();
--arrsize;
}
//扩容为原来的两倍
template<class T>
void Array<T>::extend()
{
T* newelement = new T[arrcapacity * 2];
std::copy(element, element + arrsize, newelement);
delete[]element;
element = newelement;
arrcapacity *= 2;
}
//在数组尾端插入数据
template<class T>
void Array<T>::push(const T &theElement)
{
if (arrsize >= arrcapacity) extend();
element[arrsize] = theElement;
++arrsize;
}
#endif // !ARRRAY_H
- 测试代码
#include<iostream>
#include"Array.h"
using namespace std;
int main()
{
try {
Array<int> arr;
for (int i = 0; i < 15; i++)
arr.push(i);
cout << arr << endl;
arr.pop();
cout << arr << endl;
cout << "*********测试拷贝构造函数***********" << endl;
Array<int> arr1(arr);
cout << arr1 << endl;
cout << "*****测试清空数组*******************" << endl;
arr.clear();
if (arr.empty())
{
cout << "数组是空的" << endl;
}
cout << "目前数组中的元素"<<arr.getsize() << endl;
}
catch (OutofRange &e)
{
e.what();
}
}
该例子较为简单,但麻雀虽小,五脏俱全。