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的顺序。