1 继承关系图和接口实现
实现要点:
当然,必须是类模板。
- 使用原声数组作为顺序存储空间
- 使用模板参数决定数组大小
接口实现:
template < typename T, int N >
class StaticList : public SeqList<T>
{
protected:
T m_space[N]; // 顺序存储空间,N为模板参数
public:
StaticList(); // 指定父类成员的具体值
int capacity() const;
};
继承关系图:

2 代码实现
StaticList.h
#ifndef STATICLIST_H
#define STATICLIST_H
#include "Seqlist.h"
namespace LemonLib {
template < typename T, int N >
class StaticList : public SeqList<T>
{
protected:
T m_space[N];
public:
StaticList()
{
this->m_array = m_space;
this->m_length = 0;
}
int capacity() const
{
return N;
}
};
}
#endif // STATICLIST_H
测试代码main.cpp
#include <iostream>
#include "Object.h"
#include "Exception.h"
#include "List.h"
#include "Seqlist.h"
#include "Staticlist.h"
using namespace std;
using namespace LemonLib;
int main()
{
StaticList<int, 5> sl;
for (int i=0; i<sl.capacity(); i++)
{
sl.insert(0, i);
}
for (int i=0; i<sl.length(); i++)
{
cout << sl[i] << endl;
}
sl.remove(3);
for (int i=0; i<sl.length(); i++)
{
cout << sl[i] << endl;
}
try
{
sl[5] = 0;
}
catch (const Exception& e)
{
cout << e.message() << endl;
cout << e.location() << endl;
}
return 0;
}
3 顺序存储线性表的分析
3.1 拷贝赋值带来的问题
如下代码是否正确?
StaticList<int*, 5> s1;
StaticList<int*, 5> s2;
for (int i=0; i<s1.capacity(); i++)
{
s1.insert(0, new int(i));
}
s2 = s1; // copy assignment
for (int i=0; i<s1.length(); i++)
{
delete s1[i];
delete s2[i];
}
分析: 以上代码存在很大的问题。s2 = s1这句将会进行拷贝赋值,很明显这里将进行浅拷贝,也就是说s1和s2的m_array实际上指向了同一片空间。那么我们在最后进行delete时,就对同一个堆空间内存进行了重复释放,这显然会有很大的问题,将导致程序出现未知的错误。
解决办法: 对于容器类型的类,可以考虑禁用拷贝构造和赋值操作(直接在List类中进行相关处理即可)。

3.2 误当数组使用带来的问题
下面的代码有问题吗?
int main()
{
StaticList<int, 5> list;
for (int i=0; i<list.capacity(); i++)
{
list[i] = i * i; // 将线性表当作数组使用
}
return 0;
}
问题分析: 线性表必须先插入元素,才能使用操作符[]访问元素,否则按照当前设计则会直接抛出访问越界的异常。顺序存储结构线性表提供了数组操作符重载,通过重载能够快捷方便的获取目标位置处的数据元素,在具体的使用形式上类似数组,但是由于本质不同,不能代替数组使用。

4182

被折叠的 条评论
为什么被折叠?



