第十七课、StaticList和DynamicList

1、StaticList设计要点

-类模板:
(1)、使用原生数组作为顺序存储结构

(2)、使用模板参数指定数组大小

#ifndef STATICLIST_H
#define STATICLIST_H

#include "SeqList.h"

namespace DTLib
{

/*
*StaticList设计要点-类模板
* 1.使用原生数组作为顺序存储空间
* 2.使用模板参数决定数组大小
* 3.测试
* int main()
{
   StaticList<int,5> list;

   for(int i=0; i<list.capacity(); i++)
   {
       list.insert(0,i);
   }

   for(int i=0; i<list.length(); i++)
   {
       cout << list[i]<< endl;
   }

   try
   {
       list[5] = 10;//越界
   }
   catch(Exception& e)
   {
       cout << e.message() << endl;
       cout << e.location() << endl;
   }

   return 0;
}
*/

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;
    }
};

}

#endif // STATICLIST_H
StaticList

2、DynamicList设计要点

-类模板

(1)、申请连续堆空间作为顺序存储空间

(2)、动态设置顺序存储空间大小

(3)、保证重置顺序存储空间时的异常安全性

2、异常安全性的概念

(1)、不泄露任何资源

(2)、不允许破坏数据

3、异常安全性的基本保证

如果异常被抛出

(1)、对象内的任何成员任然保持有效状态

(2)、没有数据的破坏及资源的泄漏

#ifndef DYNAMICLIST_H
#define DYNAMICLIST_H

#include "SeqList.h"
#include "Exception.h"
/*
*测试
* int main()
{
   DynamicList<int> list(5);

   for(int i=0; i<list.capacity(); i++)
   {
       list.insert(0,i);
   }

   for(int i=0; i<list.length(); i++)
   {
       cout << list[i]<< endl;
   }

   try
   {
       list[5] = 10;
   }
   catch(Exception& e)
   {
       cout << e.message() << endl;
       cout << e.location() << endl;

       list.resize(10);
       list.insert(5,100);
   }

   for(int i=0; i<list.length(); i++)
   {
       cout << list[i]<< endl;
   }

   return 0;
}
* 
*/
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];
                }

                /*这里不先删掉旧空间的原因是保证异常安全性,即最好不这样写
                 *delete[] m_array;
                 *this->m_array = array;//指向新空间
                 *this->m_length = length;
                 *this->m_capacity = capacity;
                 *因为delete时会调用析构函数,而如果析构函数里边有抛出异常,程序就会终止
                 *而m_array和m_length等还未重新赋值,这样的线性表是不可用的
                 */

                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;
    }

};

}

#endif // DYNAMICLIST_H
DynamicList

4、小结

(1)、StaticList通过模板参数定义顺序存储空间的大小

(2)、DynamicList通过动态内存申请定义顺序存储空间的大小

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

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

 

posted @ 2017-08-31 10:43  lgc202  阅读(9)  评论(0编辑  收藏  举报