我一直在用嵌套的迭代器编写一个双向链接列表。当我处理副本构造函数和operator =重载时,我遇到了Copy-swap-idiom。但是据我所知,它使用了三个规则(如果需要,可以使用一半)。但是迭代器没有析构函数,因为它们指向的“节点”不是其“属性”,而是其双重列表。
这是大学的作业,无论是否与隐式定义相同,我都被要求写一个拷贝构造函数和运算符。
我的问题是,copy-swap惯用语是否总是需要一个销毁器?如果在Iterators情况下是这样,这是否可行,还是应该使用常规的“脏”分配?以下是我的迭代器类的相关部分:
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;
}
这是我的实现,我想知道在这里使用是否明智? (我的迭代器没有析构函数,因此是我的问题。)
答案 0 :(得分:2)
您所拥有的是正确的,并且可以使用,但这不是必需的。
由于您的迭代器对节点不负责,因此它持有指向该指针的指针,它可以有一个无所事事的构造器。因为您有一个不做任何事情的析构函数,所以您不需要为任何复制/移动构造函数或复制/移动赋值运算符做任何特殊的事情。这意味着您不需要定义它们中的任何一个,并且可以遵循零规则。
请记住,您只需要在类实际负责获取和释放资源时实施3/5规则。如果您要做的只是处理POD / RAII类型,则编译器的默认值将“做正确的事”。