0.目录
1.创建异常对象时的空指针问题
2.LinkList 中的数据元素删除
3.LinkList 中遍历操作与删除操作的混合使用
4.StaticLinkList 中数据元素删除时的效率问题
5.StaticLinkList 是否需要提供析构函数?
6.StLib 是否有必要增加多维数组类?
1.创建异常对象时的空指针问题
ISSUE 1——创建异常对象时的空指针问题:
改进Exception.cpp:
在init函数中改进strdup的赋值方法
void Exception::init(const char* message, const char* file, int line)
{/* message指向的字符串有可能在栈上,有可能在堆空间,还有可能在全局数据区* strdup()将字符串复制一份到堆空间中* file:发生异常的文件名* line:发生异常的行号* m_location的长度加2,一个给":",一个给"\0"*/m_message = (message ? strdup(message) : NULL);if( file != NULL ){char sl[16] = {0};itoa(line, sl, 10);m_location = static_cast<char*>(malloc(strlen(file) + strlen(sl) + 2));if( m_location != NULL ){m_location = strcpy(m_location, file);m_location = strcat(m_location, ":");m_location = strcat(m_location, sl);}}else{m_location = NULL;}
}
2.LinkList 中的数据元素删除
ISSUE 2——LinkList 中的数据元素删除:
单链表的实现没有考虑异常安全性!
改进LinkList.h中的remove函数和clear函数:
bool remove(int i){bool ret = ((0 <= i) && (i < m_length));if( ret ){Node* current = position(i);Node* toDel = current->next;current->next = toDel->next;m_length--;destroy(toDel);}return ret;}void clear(){while ( m_header.next ){Node* toDel = m_header.next;m_header.next = toDel->next;m_length--;destroy(toDel);}}
3.LinkList 中遍历操作与删除操作的混合使用
ISSUE 3——LinkList 中遍历操作与删除操作的混合使用:
混合使用导致了m_current指向了已经被删除的结点,于是程序出错。
改进LinkList.h中的remove函数:
bool remove(int i){bool ret = ((0 <= i) && (i < m_length));if( ret ){Node* current = position(i);Node* toDel = current->next;if( m_current == toDel ){m_current = toDel->next;}current->next = toDel->next;m_length--;destroy(toDel);}return ret;}
main.cpp测试
#include <iostream>
#include "LinkList.h"using namespace std;
using namespace StLib;int main()
{LinkList<int> list;for(int i=0; i<5; i++){list.insert(i);}for(list.move(0); !list.end(); list.next()){if( list.current() == 3 ){list.remove(list.find(list.current()));cout << list.current() << endl;}}for(int i=0; i<list.length(); i++){cout << list.get(i) << endl;}return 0;
}
运行结果为:
4
0
1
2
4
4.StaticLinkList 中数据元素删除时的效率问题
ISSUE 4——StaticLinkList 中数据元素删除时的效率问题:
改进LinkList.h中的destroy函数:
void destroy(Node* pn){SNode* space = reinterpret_cast<SNode*>(m_space);SNode* psn = dynamic_cast<SNode*>(pn);for(int i=0; i<N; i++){if( psn == (space + i) ){m_used[i] = 0;psn->~SNode();break;}}}
main.cpp测试
#include <iostream>
#include "StaticLinkList.h"using namespace std;
using namespace StLib;int main()
{StaticLinkList<int, 10> list;for(int i=0; i<5; i++){list.insert(i);}list.remove(3);for(int i=0; i<list.length(); i++){cout << list.get(i) << endl;}return 0;
}
运行结果为:
0
1
2
4
5.StaticLinkList 是否需要提供析构函数?
ISSUE 5——StaticLinkList 是否需要提供析构函数?:
构造函数与析构函数不会发生多态,于是调用的是父类的析构函数!
改进StaticLinkList.h:
在子类StaticLinkList中实现析构函数:
~StaticLinkList(){this->clear();}
6.StLib 是否有必要增加多维数组类?
ISSUE 6——StLib 是否有必要增加多维数组类?:
多维数组的本质:数组的数组!
不需要定义多维数组!
使用DynamicArray创建多维数组:
#include <iostream>
#include "DynamicArray.h"using namespace std;
using namespace StLib;int main()
{DynamicArray< DynamicArray<int> > d;d.resize(3);for(int i=0; i<d.length(); i++){d[i].resize(i + 1);}for(int i=0; i<d.length(); i++){for(int j=0; j<d[i].length(); j++){d[i][j] = i * j;}}for(int i=0; i<d.length(); i++){for(int j=0; j<d[i].length(); j++){cout << d[i][j] << " ";}cout << endl;}return 0;
}
运行结果为:
0
0 1
0 2 4
实践经验:
- 是软件就有bug,因此需要不停的迭代升级,解决问题。库是一种特殊的软件产品,也会存在各种bug,也需要迭代升级,解决问题。