典型问题分析2-LinkList中数据元素删除

LinkList中的数据元素删除

LinkList<Test> list;
Test t0(0), t1(1), t2(2);

try
{
    list.insert(t0);
    list.insert(t1);    //在t1析构时抛出异常
    list.insert(t2);
    
    list.remove(1);
}
catch(...)
{
    cout << list.length() << endl;
}

在main.cpp中添加下面的代码:

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

using namespace std;
using namespace DTLib;

class Test : public Object
{
    int m_id;
public:
    Test(int id = 0)
    {
        m_id = id;
    }

    ~Test()
    {
        if(m_id == 1)
        {
            throw m_id;
        }
    }
};

int main()
{
    LinkList<Test> list;
    Test t0(0), t1(1), t2(2);

    try
    {
        list.insert(t0);
        list.insert(t1);
        list.insert(t2);

        list.remove(1);
    }
    catch(int e)
    {
        cout << e <<endl;
        cout << list.length() << endl;
    }

    return 0;

}

 程序直接挂了,原因是不允许在析构函数中抛出异常。

在Visual Studio 2010中运行,打印结果是1 3。为什么会出现3而不是2,这是由于LinkList类中的remove函数导致的。

bool remove(int i)
    {
        bool ret = ((0<=i) && (i<m_length));

        if(ret)
        {
           Node* current = position(i);

            Node* toDel = current->next;
            toDel->next = current->next;
            m_length--;
            destroy(toDel);

          //  m_length--;
        }

        return ret;
    }

在之前的程序中,我们先去destroy,然后再m_length--。当在析构函数中抛出异常时,将不会再执行m_length--。因此需要调换一下m_length--和destroy(toDel)的顺序。

在clear函数中,也存在同样的问题。

 void clear()
    {
        while(m_header.next)
        {
            Node* toDel = m_header.next;
            m_header.next = toDel->next;
            m_length--;
            destroy(toDel);
        }

        //m_length = 0;
    }

本篇文章主要是想说明,当在析构函数中抛出异常时(这是不合法的,但不排除有人就这么做),以前先的程序会导致单链表的状态发生混乱。为了增加程序的健壮性,调整m_length和destroy的顺序。

猜你喜欢

转载自www.cnblogs.com/-glb/p/12344301.html
今日推荐