复制并交换惯用语和迭代器

3
我正在编写一个嵌套迭代器的双向链表。当我在编写复制构造函数和运算符=重载时,我遇到了拷贝-交换惯用法。但是从我的理解来看,它使用了三原则(如果您愿意,还有半个)。但是迭代器没有析构函数,因为它们指向的“节点”并不是它们的“属性”,而是双向列表的。这是一个大学作业,无论如何都要写一个复制构造函数和运算符,无论是否与隐含定义相同。我的问题是,拷贝-交换惯用法是否总是需要一个析构函数?如果是迭代器情况下,这样做是否可行,还是我应该使用普通的“脏”赋值?以下是我的迭代器类的相关部分:
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;
}

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

你不需要 ForwardIterator(const ForwardIterator& right),它将由编译器隐式声明。这意味着在您的情况下,您无需关心三五法则(实际上是五)。 - UmNyobe
@UmNyobe 是的,情况就是这样,但我忘了提到(现在正在更新帖子),由于这是一项大学作业,无论如何我都被要求编写一个复制构造函数。 - Osama Asif C Infinitum
@OsamaAsifCInfinitum 我想YouClass(YourClass const&) = default;不算是自己写的吧? - WhozCraig
@WhozCraig 我怀疑他们会接受这个,他们的心态太奇怪了,相信我,我不喜欢写不必要的东西,但你能做什么呢... - Osama Asif C Infinitum
@OsamaAsifCInfinitum,我想这是留在课程评论中的一些话。祝你好运。 - WhozCraig
@WhozCraig 哈哈好的,希望他们能提高他们的标准。 - Osama Asif C Infinitum
1个回答

2
您的代码是正确的,可以运行,但实际上并不需要这样做。
由于您的迭代器并不负责节点,所以拥有一个什么都不做的析构函数是可以的。因为您有一个什么都不做的析构函数,所以您不需要为任何复制/移动构造函数或复制/移动赋值运算符进行特殊处理。这意味着您不需要定义它们,可以遵循零初始化规则。
请记住,只有当您的类实际上负责获取和释放资源时,才需要实现3/5规则。如果您只是处理POD / RAII类型,则编译器默认会“做正确的事情”。

我同意你的观点,但需要记住这是一项大学作业,而且我已经在问题中添加了这一点,他们要求我们无论如何都要写。因此,在这种情况下,你认为我的复制-交换-成语的方法正确吗?另外,通常迭代器是否需要有析构函数呢?谢谢! - Osama Asif C Infinitum
@OsamaAsifCInfinitum 你的拷贝和交换没问题。通常,如果迭代器只是指向一个元素,它们不需要析构函数。 - NathanOliver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接