数据结构(04)_数组类的实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构(04)_数组类的实现相关的知识,希望对你有一定的参考价值。

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动态申请堆空间,使得数组长度动态可变
  • 数组对象能够代替原生数组,并且使用上更安全
  • 代码优化时项目开发必不可少的环节

以上是关于数据结构(04)_数组类的实现的主要内容,如果未能解决你的问题,请参考以下文章

集合04_Set

片段中 ListView 的 setOnItemClickListener

阶段1 语言基础+高级_1-3-Java语言高级_04-集合_03 斗地主案例(单列)_2_斗地主案例的代码实现

数据结构(09)_字符串类的实现

自定义对话框片段

Java_数组