第十七课、StaticList和DynamicList
1、StaticList设计要点
-类模板:
(1)、使用原生数组作为顺序存储结构
(2)、使用模板参数指定数组大小
#ifndef STATICLIST_H #define STATICLIST_H #include "SeqList.h" namespace DTLib { /* *StaticList设计要点-类模板 * 1.使用原生数组作为顺序存储空间 * 2.使用模板参数决定数组大小 * 3.测试 * int main() { StaticList<int,5> list; for(int i=0; i<list.capacity(); i++) { list.insert(0,i); } for(int i=0; i<list.length(); i++) { cout << list[i]<< endl; } try { list[5] = 10;//越界 } catch(Exception& e) { cout << e.message() << endl; cout << e.location() << endl; } return 0; } */ template<typename T, int N> class StaticList : public SeqList<T> { protected: T m_space[N]; //顺序存储空间,N为模板参数 public: StaticList() //指定父类成员的具体值 { this->m_array = m_space; this->m_length = 0; } int capacity() const { return N; } }; } #endif // STATICLIST_H
2、DynamicList设计要点
-类模板
(1)、申请连续堆空间作为顺序存储空间
(2)、动态设置顺序存储空间大小
(3)、保证重置顺序存储空间时的异常安全性
2、异常安全性的概念
(1)、不泄露任何资源
(2)、不允许破坏数据
3、异常安全性的基本保证
如果异常被抛出
(1)、对象内的任何成员任然保持有效状态
(2)、没有数据的破坏及资源的泄漏
#ifndef DYNAMICLIST_H #define DYNAMICLIST_H #include "SeqList.h" #include "Exception.h" /* *测试 * int main() { DynamicList<int> list(5); for(int i=0; i<list.capacity(); i++) { list.insert(0,i); } for(int i=0; i<list.length(); i++) { cout << list[i]<< endl; } try { list[5] = 10; } catch(Exception& e) { cout << e.message() << endl; cout << e.location() << endl; list.resize(10); list.insert(5,100); } for(int i=0; i<list.length(); i++) { cout << list[i]<< endl; } return 0; } * */ namespace DTLib { 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 memory to create 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]; } /*这里不先删掉旧空间的原因是保证异常安全性,即最好不这样写 *delete[] m_array; *this->m_array = array;//指向新空间 *this->m_length = length; *this->m_capacity = capacity; *因为delete时会调用析构函数,而如果析构函数里边有抛出异常,程序就会终止 *而m_array和m_length等还未重新赋值,这样的线性表是不可用的 */ T* temp = this->m_array;//旧空间 this->m_array = array;//指向新空间 this->m_length = length; this->m_capacity = capacity; delete[] temp;//删掉旧空间 } else { THROW_EXCEPTION(NoEnoughMemoryException, "No memory to resize DynamicList Object..."); } } } ~DynamicList() { delete[] this->m_array; } }; } #endif // DYNAMICLIST_H
4、小结
(1)、StaticList通过模板参数定义顺序存储空间的大小
(2)、DynamicList通过动态内存申请定义顺序存储空间的大小
(3)、DynamicList支持动态重置顺序存储空间的大小
(4)、DynamicList中的resize函数实现时需要保证异常安全性