5. StaticList和DynamicList

1. StaticList设计要点

类模板

  1. 使用原生数组作为顺序存储空间
  2. 使用模板参数决定数组大小
template <typename T,int N>
class StaticList : public SeqList<T>
{
protected:
	T m_space[N];//顺序存储空间,N为模板参数
public:
	StaticList();//指定父亲成员的具体值
	int capacity() const;
};

1.1 实现

#include "SeqList.h"

namespace DragonLib
{

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

1.2具体测试

#include <iostream>
#include "StaticList.h"

using namespace std;
using namespace DragonLib;

int main()
{
    StaticList<int,5> l;
    for(int i=0;i<l.capacity();i++)
    {
        l.insert(0,i);
    }

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

    try
    {
        l[5] = 5;	//测试越界是否抛异常
    }
    catch(const Exception& e)
    {
        cout << e.message() << endl;
        cout << e.location() << endl;
    }
    return 0;
}

1.3 测试结果

在这里插入图片描述
可以看出i不合法,异常出现在SeqList.h 第85行
在这里插入图片描述
也就是这里出现异常:越界异常

2. DynamicList设计要点

类模板

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

2.1 DynamicList设计要点

函数异常安全的概念

  1. 不泄露任何资源
  2. 不允许破坏数据

函数异常安全的基本保证

如果异常被抛出

  1. 对象内的任何成员任然能保持有效状态
  2. 没有数据的破坏及资源泄露
template <typename T>
class DynamicList : public SeqList<T>
{
protected:
	int m_capacity;		//记录顺序存储空间的大小
public:
	DynamicList(int capacity);//申请空间
	int capacity() const;
	/* 重新设置顺序存储空间的大小 */
	void resize(int capacity);
	~DynamicList();//归还空间
};

2.2 实现

#ifndef DYNAMICLIST_H
#define DYNAMICLIST_H

#include "SeqList.h"
#include "Exception.h"

namespace DragonLib
{

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;//释放原来的m_array空间
            }
            else
            {
                THROW_EXCEPTION(NoEnoughMemoryException,"No memory to resize DynamicList object...");
            }
        }
    }

    ~DynamicList()//归还空间
    {
        delete[] this->m_array;
    }
};

}


#endif // DYNAMICLIST_H

2.3 玄机

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;//释放原来的m_array空间
            }
            else
            {
                THROW_EXCEPTION(NoEnoughMemoryException,"No memory to resize DynamicList object...");
            }
        }
    }

这里用了T* temp = this->m_array,而不是直接用m_array,这样子做到了异常安全。如果用m_array的话,在赋值之前就需要先delete,万一抛异常,下面的赋值操作就没有执行,并不能保证现在的线性表能否直接使用

3. 小结

  1. StaticList通过模板参数定义顺序存储空间
  2. DynamicList通过动态内存申请定义顺序存储空间
  3. DynamicList支持动态重置顺序存储空间的大小
  4. DynamicList中的resize()函数实现需要保证异常安全
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值