zoukankan      html  css  js  c++  java
  • 四、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()函数实现需要保证异常安全

  • 相关阅读:
    OpenLiveWriter博客工具
    mysql主从复制原理分析
    linux mysql主从复制配置
    linux mysql数据库安装
    linux 下安装maven私服
    eclipse新建maven项目和聚合项目
    入门Kubernetes -基础概念
    Java中5种List的去重方法及它们的效率对比,你用对了吗?
    谈一谈程序员的职业发展路线
    虚拟机中如何Linux系统如何访问PC硬盘中的文件(如何将windows下的文件夹挂载到linux虚拟机下)
  • 原文地址:https://www.cnblogs.com/chenke1731/p/9480944.html
Copyright © 2011-2022 走看看