版权声明:QQ:763905926 未经允许请勿转载,转载请注明出处! https://blog.csdn.net/lms1008611/article/details/81812150
在C或C++的原生数组里,有一点不好的就是数组越界是察觉不到,代码也不会提醒,至于越界产生的bug什么时候引发系统问题,我们也无从知晓。在这里我们可以创建一个数组类,内部包含数组长度、数组越界访问时能主动发现。
数组类的创建我们还是按照顺序表的思路,创建一个Array类,实现基本的操作,再创建StaticArray与DynamicArray一个静态一个动态数组类,数组存储位置及大小,均在这两个子类完成,同时提供数组类对象间的赋值。
首先我们来看下父类Array,采用类模板方式,继承自MyObject类,并完成基本的数组操作
#ifndef __ARRAY_H__
#define __ARRAY_H__
#include "MyObject.h"
#include "MyException"
namespace MyLib
{
template <typename T>
class Array : public MyObject
{
protected:
T* m_array; //指针
public:
virtual bool set(int index, const T& e) //设置固定位置的值
{
bool ret = ( (0 <= index)&&(index <length()) );
if (ret)
{
m_array[index] = e;
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Index Out Of Bounds Array");
}
return ret;
}
virtual bool get(int index, T& e) //获取固定位置的值
{
bool ret = ( (0 <= index)&&(index < length()) );
if (ret)
{
e = m_array[index];
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Index Out Of Bounds Array");
}
}
T& operator[](int index) //重载[]操作符,使得类能想数组那样使用
{
bool ret = ( (0 <= index)&&(index < length()) );
if (ret)
{
return m_array[index];
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Index Out Of Bounds Array");
}
}
T operator[](int index) const //重载const类的[]
{
return const_cast<Array<T>&>(*this)[index];
}
virtual int length() = 0; //提供一个获取数组长度的纯虚函数,在子类中实现
};
}
#endif //__ARRAY_H__
StaticArray类,继承自父类,数组空间由在栈提供
#ifndef __STATIC_H__
#define __STATIC_H__
#include "Array.h"
namespace MyLib
{
template <typename T, int N>
class StaticArray : public Array<T>
{
private:
T array[N]; //分配数组空间
int m_length; //数组长度
public:
StaticArray()
{
m_array = array;
m_length = N;
}
StaticArray(const StaticArray<T, N>& obj) //重写拷贝构造函数
{
m_array = array;
for (int i=0; i<obj.m_length; i++)
{
m_array[i] = obj[i];
}
m_length = obj.m_length;
}
StaticArray<T, N>& operator= (const StaticArray<T, N>& obj) //重写赋值构造函数
{
if (this != &obj)
{
for (int i=0; i<m_length; i++)
{
m_array[i] = obj[i];
}
}
return *this;
}
int length() //将继承自父类Array的length()函数实现
{
return m_length;
}
};
}
#endif //__STATIC_H__
下边是DynamicArray子类,与StaticArray类似,只是数组的空间所在的位置是在堆空间上
#ifndef __DYNAMICARRAY_H__
#define __DYNAMICARRAY_H__
#include "Array.h"
namespace MyLib
{
template <typename T>
class DynamicArray : public Array<T>
{
private:
int m_length;
public:
DynamicArray(int length)
{
m_array = new T[length]; //构造函数中指定数组长度,并分配堆空间
if (m_array)
{
m_length = length;
}
else
{
THROW_EXCEPTION(NoEnoughtMemoryException, "No Enought Memory to Create DynamicArray...");
}
}
DynamicArray(const DynamicArray<T>& obj) //重写拷贝构造函数
{
T* array = new T[obj.m_length];
if (array)
{
m_array = array;
m_length = obj.m_length;
for (int i=0; i<m_length; i++)
{
m_array[i] = obj[i];
}
}
else
{
THROW_EXCEPTION(NoEnoughtMemoryException, "No Enought Memory to Create DynamicArray...");
}
}
DynamicArray<T>& operator=(const DynamicArray<T>& obj) //重写赋值构造函数
{
if (this != &obj)
{
for (int i=0; i<m_length; i++)
{
m_array[i] = obj[i];
}
}
return *this;
}
void resize(int length) //重定义数组大小
{
T* array = new T[length];
if (array)
{
int len = m_length < length ? m_length : length;
for (int i=0; i<len; i++)
{
array[i] = m_array[i];
}
T* temp = m_array;
m_array = array;
m_length = length;
delete[] temp;
}
else
{
THROW_EXCEPTION(NoEnoughtMemoryException, "No Enought Memory to Create DynamicArray...");
}
}
int length() //实现继承自父类的length()函数
{
return m_length;
}
};
}
#endif //__DYNAMICARRAY_H__
上边就把Array、StaticArray、DynamicArray实现完了,这里我们将他们都实现在头文件中,也可以分开到源文件中,下边我们在main函数中调用一下
#include <iostream>
#include "StaticArray.h"
#include "DynamicArray.h"
using namespace std;
using namespace MyLib;
int main()
{
cout << "StaticArray..........." << endl;
StaticArray<int, 10> list1;
for (int i=0; i<list1.length(); i++)
{
list1[i] = i; //设置数组元素
}
for (int i=0; i<list1.length(); i++)
{
cout << list1[i] << " " ;
}
cout << endl << "DynamicArray.........." << endl;
DynamicArray<int> list2(10);
for (int i=0; i<list2.length(); i++)
{
list2[i] = i; //设置数组元素
}
for (int i=0; i<list2.length(); i++)
{
cout << list2[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
编译执行
到这里我们的数组类就创建完成了,也可以按照需求增减功能。