数据结构--线性表之DynamicList类

DynamicList类的设计要点:

同样使用类模板

继承自SeqList

申请连续的堆空间作为顺序存储空间

动态设置顺序存储空间的大小

保证重置顺序存储空间时的异常安全性。

什么叫做异常安全:不泄露任何资源和不允许破坏需要的数据。

函数异常安全的保障:如果有异常抛出时,对象内的任何成员仍然能保持有效状态,没有数据的破坏及资源泄漏。

先看总体设计:

    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(int capacity)//动态申请空间
        {
            this->m_array = new T[capacity];
            if(this->m_array != NULL)
            {
                this->m_length = 0;
                this->m_capacity = capacity;
            }
            else
            {
                //申请失败则抛出异常
            }
        }
实现就是在堆空间中申请capacity大小的T类型的数组,并将m_array指向它。

二、获取最大容量

        int capacity() const
        {
            return m_capacity;
        }
直接返回代表空间最大容量的m_capacity成员变量。

三、重置空间大小

        //重新设置顺序存储空间的大小,保证异常安全(异常发生后数据不会丢失)
        void resize(int capacity)
        {
            if(capacity != m_capacity )
            {
                T* array = new T[capacity]; //不直接操作this->m_array的目的就是保证原先的数据不会丢失

                if(array != NULL)
                {
                    int length = (this->m_length < capacity ? this->m_length : capacity);//操作长度为少的那个,不会出现越界的情况

                    for(int i = 0; i < length; i++)
                    {
                        //array多余的空间先空着等待数据插入
                        array[i] = this->m_array[i];//可能发生异常:由于T是泛指类型,当T是类类型时可能赋值操作符会被重载,
                        //                                        而重载函数中设有异常抛出时就可能发送异常,但是没办法,要是出现了异常就不是我们的事了。
                    }

                    T* temp = this->m_array;//使用temp的原因:如果直接在此处使用delete[]this->m_array可能
                    //                         触发析构函数调用(T为类类型时)而抛出一些异常,程序也会从当前语句返回,那后面的语句就不会执行了
                    //如何会抛出异常?当析构函数中设置了异常抛出时,就可能抛出异常
                    this->m_array = array;
                    this->m_length = length;
                    this->m_capacity = capacity;

                    delete []temp;//此处delete保证了线性表的指向空间、当前表长、最大容量得到保存,所以数据不会丢失,保证了异常安全
                }
                else
                {
                     //申请失败抛出异常
                }


            }
        }
具体代码功能已经在程序所在位置明确注释,更方便理解。

四、释放空间

        ~DynamicList()//归还空间
        {
            delete [] this->m_array;
        }
在析构函数中delete申请的空间即可。

测试代码和StaticList类几乎一样,只是他们的存储位置不同而已,其他操作仍然相同,详见上一篇测试代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值