DynamicList
在上一片博客里说到了一种基于顺序存储结构的实现,即StaticList,这一篇说另外一种DynamicList。这个类也要继承SeqList类,初始化父类的成员变量和重写capacity。StaticList和DynamicList都是继承自SeqList,大部分的实现都是一样的,那么不一样的就是DynamicList相比于StaticList来说,它的大小是可以动态的发生变化的。
设计要点:
类模板
申请连续的堆空间作为顺序存储的空间
动态设置顺序存储空间的大小
在重置空间大小的时候,要做到异常安全
程序实现:
template <typename T>
class DynamicList : public SeqList<T>
{
protected:
int m_capacity;
public:
DynamicList(int capacity);
int capacity() const;
void resize(int capacity);
~DynamicList();
};
StaticList是直接使用一维数组当做内存,而且内存大小一经定义就无法改变,所以直接定义了一个一维数组的成员变量,我们就有了地址和容量信息。长度信息在成员函数初始化。但是在DynamicList里,我们申请一块连续的堆空间来存储,所以我们要定义一个capacity成员变量记录容量这个信息。地址和长度的初始化放在成员函数就可以。
代码实现:
template <typename T>
class DynamicList : public SeqList<T>
{
protected:
int m_capacity;
public:
DynamicList(int capacity)
{
this->m_array = new T[capacity];
if(this->m_array != NULL)
{
this->m_length = 0;
this->m_capacity = capacity;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory to creat DynamicList Object ...");
}
}
int capacity() const
{
return m_capacity;
}
void resize(int capacity)
{
if( capacity != m_capacity )
{
/*新生成一块内存*/
T* array = new T[capacity];
if(array != NULL)
{
/*原长度小于新长度,全部保留,否则只保留新长度的元素个数*/
int length = (this->m_length < capacity ? this->m_length : capacity);
for(int i=0; i<length; i++)
{
array[i] = this->m_array[i];
}
/*定义一个指向原来内存的局部变量用于后面释放*/
T* temp = this->m_array;
this->m_array = array;
this->m_length = length;
this->m_capacity = capacity;
delete[] temp;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException,"No enough memory to resize DynamicList Object ...");
}
}
}
~DynamicList()
{
delete[] this->m_array;
}
};
小程序讲解:
构造函数申请了用于存储的空间,并且初始化了三个关于线性表的信息。
resize这个函数用来动态的改变顺序存储空间大小,思路是重新申请一块空间,把可以保留的值拷贝到新的空间,然后把旧的空间释放掉,这个过程要考虑异常安全。
总结:
这个相比上一种线性表,多了可以动态设置存储空间的功能。