C++ 中支持原生数组, 但由于原生数组的天然缺陷 (不能获取长度信息, 越界访问不会报错...), 我们有必要来开发自己的数组类, 从而解决这些问题.
数组类的继承关系如图:
19. 数组类的实现_1
19.1. 抽象类模板 Array
需求分析:
1, 由于线性表, 不能作为数组直接使用, 我们需要自己实现一个数组类来代替原生数组.
2, 解决原生数组越界访问不会报错的问题
3, 提供数组的长度信息
19.2.Array 设计要点:
抽象类模本, 存储空间的位置和大小由子类指定.
重载数组操作符, 并判断访问下标是否越界 (合法)
提供数组长度信息的抽象访问函数
提供数组对象间的复制操作 (通过重载拷贝构造函数和赋值操作符完成)
- template <typename T>
- class Array : public Object
- {
- protected:
- T *m_array;
- public:
- T& operator [] (int index)
- T operator [] (int index) const
- bool get(int index, const T& e)
- bool set(int index, const T& e)
- virtual int length(void) = 0;
- };
19.2.1. Array 的实现
- #ifndef ARRRY_H
- #define ARRRY_H
- #include "Object.h"
- #include "Exception.h"
- namespace DTLib
- {
- template <typename T>
- class Array : public Object
- {
- protected:
- T *m_array;
- public:
- T& operator [] (int index)
- {
- if( (index>=0) && (index<length()) )
- {
- return m_array[index];
- }
- else
- {
- THROW_EXCEPTION(IndexOutOfBoundsException, "array index out of range...");
- }
- }
- T operator [] (int index) const
- {
- return const_cast<Array<T>&>(*this)[index];
- }
- bool get(int index, const T& e)
- {
- bool ret = (index>=0) && (index<length());
- if( ret )
- {
- e = m_array[index];
- }
- return ret;
- }
- bool set(int index, const T& e)
- {
- bool ret = (index>=0) && (index<length);
- if( ret )
- {
- m_array[index] = e;
- }
- return ret;
- }
- virtual int length(void) = 0;
- };
- }
- #endif // ARRRY_H
19.3.StaticArray 的实现
设计要点:
封装原生数组;
使用模板参数决定数组大小
实现函数返回数组长度
拷贝构造和赋值重载
- template <typename T, int N>
- class StaticArray : public Array<T>
- protected:
- T m_space[N];
- public:
- StaticArray()
- // 提供拷贝构造喊赋值重载函数, 实现数组的拷贝
StaticArray(const StaticArray<T, N>& obj)
- T& operator = (const StaticArray<T, N>& obj)
- int length(void)
- };
19.3.1. StaticArray 的实现
- #ifndef STATICARRAY_H
- #define STATICARRAY_H
- #include "Array.h"
- namespace DTLib
- {
- template <typename T, int N>
- class StaticArray : public Array<T>
- {
- protected:
- T m_space[N];
- public:
- StaticArray()
- {
- this->m_array = m_space;
- }
- StaticArray(const StaticArray<T, N>& obj)
- {
- this->m_array = m_space;
- for(int i=0; i<length();i++) // 数组元素拷贝
- {
- m_space[i] = obj.m_space[i];
- }
- }
- T& operator ==(const StaticArray<T, N>& obj)
- {
- if(this != &obj)
- {
- this->m_array = m_space;
- for(int i=0; i<length();i++)
- {
- m_space[i] = obj.m_space[i];
- }
- }
- }
- int length(void)
- {
- return N;
- }
- };
- }
- #endif // STATICARRAY_H
20. 数组类的实现_2
20.1.DynamicArray 的实现
设计要点: 类模板
动态确定内部数组空间的大小
实现函数返回数组的长度
拷贝构造和赋值操作
- template <typename T>
- class DynamicArray : public Array<T>
- {
- protected:
- int m_length;
- public:
- DynamicArray(int length)
- DynamicArray(const DynamicArray<T>& obj)
- DynamicArray<T>& operator = (const DynamicArray<T>& obj)
- void resize(int length)
- ~DynamicArray()
- };
20.2.DynamicArray 代码优化
DynamicArray 类中的函数实现存在重复的逻辑, 可以进行代码优化.
重复代码逻辑的抽象:
- init 函数中实现对象构造时的初始化操作
- copy 函数负责从堆空间中申请内存, 并执行拷贝构造操作
- updata 将指定的堆空间作为内部存储数组使用
20.2.1. DynamicArray 实现
- #ifndef DYNAMICLIST_H
- #define DYNAMICLIST_H
- #include "SeqList.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 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 memory to create DynamicList object ...");
- }
- }
- }
- ~DynamicList()
- {
- delete[] this->m_array;
- }
- };
- }
- #endif // DYNAMICLIST_H
总结:
StaticArray 通过封装原生数组的方式, 实现数组类
DynamicArray 动态申请堆空间, 使得数组长度动态可变
数组对象能够代替原生数组, 并且使用上更安全
代码优化时项目开发必不可少的环节
来源: http://www.bubuko.com/infodetail-2638323.html