参考教程《数据结构与算法分析 C++描述 》第三版和第四版
这次写的过程中,发现的两个新的 问题:
第一:自己定义的数据结构UDT如果需要使用C++11中的范围for语句,需要定义begin和end函数。如果遍历的是常量对象,则要有相应的常量对象可用的begin和end函数。
声明形式如下:
iterator begin();
const_iterator begin() const;
第二个问题主要的问题集中在operator=函数的实现。有两个大类的实现:
1、使用自赋值检查->先创建临时的对象(防止申请内存过程中出现异常,便于处理异常,而且不损坏原对象)->释放原对象->接管临时对象
2、第二种是使用copy and swap,这种方法使用的时候(1)如果直接使用std::swap,则需要定义移动赋值函数,并且移动赋值函数中需要对类成员一一进行交换,而不能直接交换对象,否则会出现赋值操作符反复的调用,最后堆栈溢出。(2)使用自己定义的swap函数,在这个里面可以使用std::swap()函数,把类成员一一交换。
这个程序还有很多地方需要补充,主要体现在错误控制方面,比如没有对传入erase函数的迭代器进行有效性检查(如果传入的是指向另一个对象的迭代器呢?)等等。。。
记录一下今天的代码:
首先是mylist.h文件,定义了List模板
#ifndef MYLIST_H
#define MYLIST_H
#include<algorithm> // 在 赋值操作符重载的时候,可能会用到std::swap函数
/*
* 双向链表模板,包含表头节点(m_head指向)和尾节点(m_tail指向)
*/
template<typename Object>
class List
{
public:
typedef unsigned int size_t;
typedef Object value_type;
private:
// 节点通过struct定义,数据成员虽然默认都为public的访问级别,但是其本身是private的
struct Node{
value_type sNode_data; // 存储的内容
Node *sNode_pprev; // 前一个节点
Node *sNode_pnext; // 后一个节点
Node(const value_type & data = value_type(),
Node *prev = nullptr,
Node *next = nullptr)
: sNode_data(data), sNode_pprev(prev), sNode_pnext(next){}
};
public:
// 定义常迭代器和普通迭代器
class const_iterator{
public:
const_iterator() : p_current(nullptr) {}
const value_type & operator*() const {
return retrieve();
}
co