【问题标题】:Implementing iterator for custom array为自定义数组实现迭代器
【发布时间】:2018-08-25 23:52:40
【问题描述】:

我即将创建自己的可迭代通用数组实现。我创建了一个名为Iterable<E> 的接口,它将“强制”其所有继承者实现其所有纯虚方法。该接口有以下原型:

可迭代

public:
virtual Iterable<E>& operator=(const Iterable<E>& iter) = 0;
virtual bool operator==(const Iterable<E>& iter) const = 0;
virtual bool operator!=(const Iterable<E>& iter) const = 0;
virtual Iterable<E>& operator++() = 0;
virtual E& operator*() = 0;

在我的Array&lt;E&gt; 中,我创建了以下方法:

Iterable<E> begin();
Iterable<E> end();

Array&lt;E&gt; 类具有 Iterable&lt;E&gt; 的匿名嵌套实现,如下所示:

ArrayIterator

class ArrayIterator : public Iterable<E> {
public:
    ArrayIterator(Array<E>* array, const int index) : _array(array), _index(index) {};

    ArrayIterator& operator=(const ArrayIterator& iter) override { _index = iter._index; return *this; }
    bool operator==(const ArrayIterator& iter) const override { return _index == iter._index; }
    bool operator!=(const ArrayIterator& iter) const override { return _index != iter._index; }
    ArrayIterator& operator++() override { _index++; return *this; }
    E& operator*() override { return _array[_index]; }
private:
    Array<E>* _array;
    int _index;
};

然后我在 begin()end() 方法中返回了 ArrayIterator 实例:

  Iterable<E> Array<E>::begin() {
     return ArrayIterator(this, 0);
  }

  Iterable<E> Array<E>::end() {
     return ArrayIterator(this, this->length()); //length() returns array size
  }

一切都编译得很好,但是当我尝试使用每个时,我会抛出一个编译时错误: 'Iterable cannon 可实例化抽象类' 在下面的例子中:

int main() {
   Array<int> array{1, 2, 3, 4};
   for(int i : array) {  //<- error points to this line

    }
}

作为Iterable,我返回了ArrayIterator,这是它的实现,它不应该通过多态工作吗?

【问题讨论】:

  • 没有理由将Iterable 的构造函数设为私有。它具有纯虚函数,您不能实例化具有纯虚函数的对象。
  • 我认为这里不需要运行时多态性。
  • begin() for const 实例不应返回非常量迭代器。
  • 感谢大家的回复。 @SergeyA - 我不认为返回 ArrayIterator 是个好主意,它是 Array 的私有类,还是有原因? liliscent - 感谢您指出,甚至没有注意到。

标签: c++ arrays iterator iterable


【解决方案1】:

您的beginend 函数都返回Iterable&lt;E&gt;,而不是ArrayIterator。您创建要返回的ArrayIterator切片,并且只返回创建对象的基础部分。

因为这需要创建一个抽象类,所以会出现编译错误。

【讨论】:

  • 感谢您的回答。如何“切片”?有什么方法可以将 ArrayIterator 保留在类中?
  • 它甚至不能被切片,因为Iterable&lt;E&gt; 是抽象的。正如 OP 所发现的那样,尝试使用它不会编译。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-30
  • 2019-08-21
  • 1970-01-01
  • 2014-05-23
  • 2015-05-26
  • 2016-11-04
  • 1970-01-01
相关资源
最近更新 更多