四、StaticList 和 DynamicList

四、StaticList 和 DynamicList

1、StaticList类模板

StaticList 的设计要点:类模板

  • 使用原生数组作为顺序存储空间
  • 使用模板参数决定数组大小
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;
    }
};

2、DynamicList类模板

DynamicList设计要点:类模板

  • 申请连续堆空间作为顺序存储空间
  • 动态设置顺序存储空间的大小
  • 保证重置顺序存储空间时的异常安全性

异常安全性的概念:

  • 不泄露任何资源
  • 不允许破坏数据

函数异常安全的基本保证:如果异常被抛出

  • 对象内的任何成员任然能保持有效状态
  • 没有数据的破坏及资源泄漏

DynamicList 类模板:

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 creat DynamicList object...");
        }
    }

    int capacity() const
    {
        return 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[i] = this->m_array[i];
                    // 这里也可能发生异常,但是也不会怎样,当前的线性表对象不会发生改变,只是array会被泄漏
                    // 如果这里发生异常,说明泛指类型T所指代的具体类型所导致的,是第三方工程师代码问题
                }

                // delete this->m_array;
                // 没有直接操作this->m_array,是因为有可能在析构的时候会发生异常,函数异常返回,导致this->m_array等没法赋值,这就没法保证当前的线性表this->m_array合法可用
                // 思路是先用一个临时指针指向原先的顺序存储空间,然后将线性表赋值,改为重置之后的线性表,然后再delete[] temp,这时就算再发生异常,线性表也是合法可用的
                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;
    }
};

3、小结

StaticList通过模板参数定义顺序存储空间

DynamicList通过动态内存申请定义顺序存储空间

DynamicList支持动态重置顺序存储空间的大小

DynamicList中的resize()函数实现需要保证异常安全

原文链接: https://www.cnblogs.com/chenke1731/p/9480944.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    四、StaticList 和 DynamicList

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/279429

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月15日 上午4:10
下一篇 2023年2月15日 上午4:11

相关推荐