复制和交换习语和迭代器

Copy and Swap Idiom and Iterators

本文关键字:迭代器 习语 交换 复制      更新时间:2023-10-16

我一直在用嵌套迭代器编写一个双向链表。当我在处理复制构造函数和运算符=重载时,我遇到了复制交换习语。但据我所知,它使用了三法则(如果你愿意,也可以用一个半法则(。但是迭代器没有析构函数,因为它们指向的"节点"不是它们的"属性",而是它的双重列表。

这是一个大学作业,无论情况如何,我都被要求编写一个复制构造函数和运算符,无论它是否与隐式定义相同。

我的问题是复制交换成语总是需要有一个设计者吗?如果是这样,在迭代器的情况下,这会起作用还是我应该使用正常的"脏"赋值?以下是我的迭代器类的相关部分:

template<class T>
class List<T>::ForwardIterator {
private:
Node<T> *current;
public:
ForwardIterator(Node<T> *curr = nullptr) : current(curr) {}
ForwardIterator(const ForwardIterator& right) : current(right.current) {}
...
...

上面的部分显示了迭代器的构造函数和私有数据。下面的部分显示了它的分配和交换功能。

friend void swap(ForwardIterator& first, ForwardIterator& second) {
using std::swap;
swap(first.current, second.current);
}
ForwardIterator& operator=(ForwardIterator right) {
swap(*this, right);
return *this;
}

这是我的实现,我想知道在这里使用是否明智?(我的迭代器没有析构函数,因此我的问题(。

你所拥有的是正确的,可以工作,但不是必需的。

由于您的迭代器不负责节点,因此它持有指向它的指针,因此可以不执行任何操作的节点。 因为您有一个不执行任何操作的析构函数,所以不需要对任何复制/移动构造函数或复制/移动赋值运算符执行任何特殊操作。 这意味着您不需要定义它们中的任何一个,您可以遵循零规则。

请记住,只有当您的类实际负责获取和释放资源时,您才需要实现 3 规则/5 规则。 如果你所做的只是处理 POD/RAII 类型,那么编译器默认值将"做正确的事情"。