StaticList 和 DynamicList(七)
A、StaticList 的設計要點:首先必須是一個類模板。其次是使用原生數組作為順序存儲空間,最後是使用模板參數決定數組大小。定義如下
template < typename T, int N > class StaticList : public SeqList<T> { protected: T m_space[N]; // 順序存儲空間,N 為模板參數 public: StaticList(); // 指定父類成員的具體值 int capacity() const; };
我們下來來實現 StaticList ,代碼如下
StaticList.h 源碼
#ifndef STATICLIST_H #define STATICLIST_H #include "Seqlist.h" namespace DTLib { 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
我們來寫個測試代碼測試下這個 StaticList ,main.cpp 代碼如下
#include <iostream> #include "StaticList.h" using namespace std; using namespace DTLib; int main() { StaticList<int, 5> l; for(int i=0; i<l.capacity(); i++) { l.insert(0, i); } for(int i=0; i<l.capacity(); i++) { cout << l[i] << endl; } l[0] *= l[0]; for(int i=0; i<l.capacity(); i++) { cout << l[i] << endl; } try { l[5] = 5; } catch(const Exception& e) { cout << e.message() << endl; cout << e.location() << endl; } return 0; }
我們來看看輸出結果
結果正是我們想要的,這個 StaticList 類已經實現完畢。接下來我們再來實現 DynamicList 類。
B、DynamicList 類的設計要點:它也必須得是一個類模板。申請連續堆空間作為順序存儲空間;動態設置順序存儲空間的大小;保證重置順序存儲空間時的異常安全性。
a> 函數異常安全的概念:1、不泄露任何資源;2、不允許破壞數據。
b> 函數異常安全的基本保證,如果對象被拋出:對象內的任何成員仍然能保持有效狀態;沒有數據的破壞及資源泄漏。
下來我們來看看它的定義
template < typename T > class DynamicList : public SeqList<T> { protected: int m_capacity; // 順序存儲空間的大小 public: DynamicList(int capacity); // 申請空間 int capacity() const; // 重新設置順序存儲空間的大小 void resize(int capacity); ~DynamicList(); // 歸還空間 };
下來我們來實現這個 DynamicList 類
DynamicList.h 源碼
#ifndef DYNAMICLIST_H #define DYNAMICLIST_H #include "SeqList.h" #include "Exception.h" 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 ..."); } } 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 memory to resize DynamicList Object ..."); } } } ~DynamicList() { delete[] this->m_array; } }; } #endif // DYNAMICLIST_H
我們同樣還是寫個示例代碼來驗證下這個 DynamicList 類,main.cpp 代碼如下
#include <iostream> #include "DynamicList.h" using namespace std; using namespace DTLib; int main() { DynamicList<int> l(5); for(int i=0; i<l.capacity(); i++) { l.insert(0, i); } for(int i=0; i<l.length(); i++) { cout << l[i] << endl; } l[0] *= l[0]; for(int i=0; i<l.length(); i++) { cout << l[i] << endl; } try { l[5] = 5; } catch(const Exception& e) { cout << e.message() << endl; cout << e.location() << endl; l.resize(10); l.insert(4, 40); } l[5] = 5; for(int i=0; i<l.length(); i++) { cout << l[i] << endl; } l.resize(3); for(int i=0; i<l.length(); i++) { cout << l[i] << endl; } return 0; }
我們來看看編譯結果
結果已經正確輸出了。那麽回到我們之前的問題:是否能將 DynamicList 作為 StaticList 的子類實現呢?答案肯定是不行的,因為 DynamicList 和 StaticList 兩個類在存儲結構上完全是不同的。因此他們是等價的,所以不能將 DynamicList 作為 StaticList 的子類實現。通過今天對 DynamicList 和 StaticList 的學習,總結如下:1、StaticList 通過模板參數定義順序存儲空間;2、DynamicList 通過動態內存申請定義順序存儲空間;3、DynamicList 支持動態重置順序存儲空間的大小;4、DynamicList 中的 resize() 函數實現需要保證異常安全。
StaticList 和 DynamicList(七)