在实现动态数组的时候,我们知道需要重载[]运算符,实现成员函数pop等,但是实现这些函数的时候需要注意一个问题,就是数组越界的问题,所以我基于这个问题写了一个异常类OutofRange,让数组下标超过数组长度时抛出一个匿名异常,当pop成员函数执行到数组为空时,也抛出异常。

下面是代码实现:

#include<iostream>
#include<cstdlib>

using namespace std;

enum{
    NOSPACE,
    OUTOFRANGE,
    UNKNOWN,
};

class OutofRange
{
    public:
        OutofRange():m_flag(NOSPACE){}
        OutofRange(int index_, int length_): m_flag(OUTOFRANGE),
             m_index(index_), m_length(length_) {}
        ~OutofRange() {};
        void what(){
            if(m_flag == NOSPACE)
            {
                cout << "there is no enough space to pop, because it is empty" << endl;
            }
            else if(m_flag == OUTOFRANGE)
            {
                cout << "the index is " << m_index << endl;
                cout << "the length is " << m_length << endl;
                cout << "it is out of range!" << endl;
            }
            else
            {
                cout << "unknown exception!" << endl;
            }
        }

    private:
        int m_flag;
        int m_index;
        int m_length;
};

class Array
{
    public:
        Array();
        ~Array() {
            free(m_point);
        };
        int operator[](int ind_);
        int push(int ele);
        int pop();
        int* begin() {
            return m_point;
        }
        int* end(){
            return m_point + m_length;
        }
        int length(){
            return m_length;
        }
        int capacity()
        {
            return m_space;
        }

    private:
        int* m_point;
        int m_length;
        int m_space;

        static const int default_space = 50;

};

Array::Array():m_length(0), m_space(default_space)
{
    m_point = (int*)malloc(default_space * sizeof(int));
}

int Array::operator[](int ind_)
{
    if(ind_ > m_length)
        throw OutofRange(ind_, m_length);
    return *(m_point+ind_);
}

int Array::push(int ele)
{
    if(m_length >= m_space)
    {
        m_space += default_space;
        m_point = (int*)realloc(m_point, sizeof(int) * m_space);
    }

    m_point[m_length] = ele;
    m_length++;

    return m_length;
}

int Array::pop()
{
    if(m_length <= 0)
        throw OutofRange();
    return m_point[m_length--];
}

template<class T>
void Print(T first, T end)
{
    for(; first != end; ++first)
    {
        cout << *first << " ";
    }
    cout << endl;
}

int main()
{
    Array arr;
    cout << "length:" << arr.length() << endl;
    for(int i = 0; i <= 51; ++i)
    {
        arr.push(i);
    }
    cout << "init:";
    Print(arr.begin(), arr.end());
    cout << "length:" << arr.length() << endl;
    cout << "spcae:" << arr.capacity() << endl;

    try
    {
        cout << "access 101 index(must out of range): " << arr[100] << endl;
    }
    catch(OutofRange& e)
    {
        e.what();
    }

    for(int i = 0; i < 52; ++i)
    {
        try
        {
            arr.pop();
        }
        catch(OutofRange& e)
        {
            e.what();
        }
    }

    return 0;
}

代码输出结果:
图片说明

在上面的代码中,我故意使用下标超过数组长度。看看能不能捕获到这个异常,输出显示,index > length,说明异常时捕获到了的,pop同理。当然,这个例子实现的动态数组只是基于int类型的,如果有兴趣实现全类型,可以使用模板编程的技巧。