1,顺序存储线性表两个问题:
1,当做数组误用;
2,效率有隐患;
2,本文解决第一个功能上的问题,创建一个数组类代替顺序存储结构中的数组访问操作符;
3,本文目标:
1,完成 Array 类的具体实现;
2,完成 StaticArray 类的具体实现,替代原生数组;
4,需求分析:
1,创建数组类代替原生数组的使用;
1,数组类包含长度信息;
2,数组类能够主动发现越界访问;
5,Array 设计要点:
1,抽象类模板,存储空间的位置和大小由子类完成;
2,重载数组操作符,判断访问下标是否合法(满足上面第二点,且满足原生数组访问操作);
3,提供数组长度的抽象访问函数(满足上面第一点);
4,提供数组对象间的复制操作(附加的功能);
6,Array 类的声明;
7,Array 数组抽象类实现:
1 #ifndef ARRAY_H 2 #define ARRAY_H 3 4 #include "Object.h" 5 #include "Exception.h" 6 7 namespace DTLib 8 { 9 10 template <typename T> 11 class Array : public Object 12 { 13 protected: 14 T* m_array; 15 16 public: 17 virtual bool set(int i, const T& e) // O(1) 18 { 19 bool ret = ((0 <= i ) && (i < length())); 20 21 if( ret ) 22 { 23 m_array[i] = e; 24 } 25 26 return ret; 27 } 28 29 virtual bool get(int i, T& e) const // O(1) 30 { 31 bool ret = ((0 <= i) && (i < length())); 32 33 if( ret ) 34 { 35 e = m_array[i]; 36 } 37 38 return ret; 39 } 40 41 //数组访问操作符 42 T& operator[] (int i) // O(1) 43 { 44 bool ret = ((0 <= i) && (i < length())); 45 46 if( ret ) 47 { 48 return m_array[i]; 49 } 50 else 51 { 52 THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invalid ..."); 53 } 54 } 55 56 T operator[] (int i) const // O(1) 57 { 58 return (const_cast<Array<T>&>(*this))[i]; 59 } 60 61 /* 直接返回原生数组的首地址,为了能够通过这个函数返回数组元素,然后对数组元素排序 */ 62 T* array() const 63 { 64 return m_array; 65 } 66 67 virtual int length() const = 0; 68 }; 69 70 } 71 72 #endif // ARRAY_H
8,StaticArray 设计要点:
1,类模板(创建原生数组替代品,可以直接指定数据元素类型,所以必须是类模板):
1,封装原生数组;
1,父类中没有完成的具体元素应该保存在什么地方;
2,使用模板参数决定数组大小;
1,用成员函数来表现;
3,实现函数返回数组长度;
4,拷贝构造和赋值操作;
1,数组对象可以相互赋值的,这是附加的语义;
9,StaticArray 类的声明;
10,StaticArray 静态数组类的实现:
1 #ifndef STATICARRAY_H 2 #define STATICARRAY_H 3 4 #include "Array.h" 5 6 namespace DTLib 7 { 8 9 template <typename T, int N> 10 class StaticArray : public Array<T> 11 { 12 protected: 13 T m_space[N]; // 原生数组作为成员,被封装; 14 15 public: 16 StaticArray() // O(1) 17 { 18 this->m_array = m_space; // 父类的指针挂接到子类的原生数组上 19 } 20 21 /* 实现数组的复制操作 */ 22 StaticArray( const StaticArray<T, N>& obj) // O(n) 23 { 24 this->m_array = m_space; 25 26 for(int i=0; i<N; i++) 27 { 28 m_space[i] = obj.m_space[i]; 29 } 30 } 31 32 /* 实现数组的复制操作 */ 33 StaticArray<T, N>& operator= ( const StaticArray<T, N>& obj ) // O(n) 34 { 35 if( this != &obj ) 36 { 37 for(int i=0; i<N; i++) 38 { 39 m_space[i] = obj.m_space[i]; 40 } 41 } 42 43 return *this; 44 } 45 46 int length() const // O(1) 47 { 48 return N; 49 } 50 }; 51 52 } 53 54 #endif // STATICARRAY_H
11,StaticArray 的测试代码:
1 #include <iostream> 2 #include "StaticArray.h" 3 4 using namespace std; 5 using namespace DTLib; 6 7 int main() 8 { 9 StaticArray<int, 5> l; 10 11 for(int i=0; i<l.length(); i++) 12 { 13 l[i] = i*i; 14 } 15 16 for(int i=0; i<l.length(); i++) 17 { 18 cout << l[i] << endl; 19 } 20 21 StaticArray<int, 5> l1; 22 l1 = l; 23 24 for(int i=0; i<l1.length(); i++) 25 { 26 cout << l1[i] << endl; 27 } 28 29 l[5] = 100; 30 31 return 0; 32 }