Ответ 1
Принимая во внимание ваши ограничения по дизайну, которые вы не можете использовать шаблоны, необходимо изменить одно: добавить интерфейс IteratorImpl
. Таким образом, вы можете сделать class Iterator
из базы class Container
не виртуальной. Он должен быть не виртуальным, поскольку STL-итераторы должны иметь семантику значений. См. pimpl idiom для более подробной информации о том, как это работает!
Вот так:
typedef int value_type;
class Container
{
protected:
class IteratorImpl
{
public:
virtual void next() = 0;
virtual IteratorImpl* clone() const = 0;
virtual value_type get() const = 0;
virtual bool isEqual(const IteratorImpl& other) const = 0;
};
public:
class Iterator
{
public:
Iterator(IteratorImpl* impl) : impl(impl) {}
~Iterator() { delete impl; }
Iterator(const Iterator& other) : impl(other.impl->clone()) {}
Iterator& operator=(const Iterator& other) {
IteratorImpl* oldImpl = impl;
impl = other.impl->clone();
delete oldImpl;
}
bool operator == (const Iterator& other) const
{
return impl->isEqual(*other->impl);
}
Iterator& operator ++ ()
{
impl->next();
return *this;
}
value_type& operator*() const
{
return impl->get();
}
value_type* operator->() const
{
return &impl->get();
}
};
Container();
Container(const Container& other);
~Container();
virtual value_type& front() const=0;
virtual value_type& back() const=0;
virtual Iterator begin() const=0; //
...
};
Затем в вашем производном просто реализуем IteratorImpl:
class Linked_list:public Container
{
protected:
class IteratorImpl: public Container::IteratorImpl
{
....
};
public:
Iterator begin() const { return new IteratorImpl(firstNode); }
Iterator end() const { return new IteratorImpl(nodeAfterLastNode); }
...
};
Эти firstNode и nodeAfterLastNode - это только моя догадка - используйте все, что вам нужно для реализации интерфейса IteratorImpl...