Я и раньше сталкивался именно с этой проблемой. Хотя существуют способы решения вашей проблемы, вам, скорее всего, следует отказаться от идеи векторного базового класса. То, что вы, вероятно, должны делать вместо этого, это имитировать способ, которым сконструирован контейнер c ++ STL.
STL состоит из концепций , а не базовых классов. std::vector
является моделью концепции Container
, но не наследуется от базового класса Container
. Концепция - это набор требований, которых должна придерживаться любая модель концепции. См. эту страницу для требований к Container
, например.
Требования для Container
указывают, например, что вы должны ввести typedef типа содержимого контейнера как value_type
, а итераторы typedef как iterator
и const_iterator
. Кроме того, вы должны определить функции begin()
и end()
, возвращающие итераторы, и т. Д.
Затем вам нужно будет изменить функции, которые работают с вашим базовым классом Vector
, чтобы вместо этого работать с любым классом, который соответствует требованиям, налагаемым концепцией. Это можно сделать, сделав функции шаблонными. Вам не обязательно придерживаться концепций, используемых STL, вы также можете придумать свои собственные. Следование концепциям, определенным в STL, дает дополнительное преимущество, заключающееся в том, что алгоритмы STL (например, std::sort
) могут работать с вашими контейнерами.
Быстрый пример:
class VectorImplA
{
public:
typedef VectorImplAIterator iterator;
iterator begin();
iterator end();
};
class VectorImplB
{
public:
typedef VectorImplBIterator iterator;
iterator begin();
iterator end();
};
template <typename VectorConcept>
void doSomeOperations(VectorConcept &container)
{
VectorConcept::iterator it;
it = container.begin();
}
int main()
{
VectorImplA vecA;
VectorImplB vecB;
doSomeOperations(vecA); // Compiles!
doSomeOperations(vecB); // Compiles as well!
}
В качестве бонуса, чтобы ответить на исходный вопрос, рассмотрим следующий дизайн (хотя я бы не пошел по этому пути!):
struct IteratorBase
{
virtual void next() = 0;
};
struct IteratorA : IteratorBase
{
void next() {};
};
struct IteratorB : IteratorBase
{
void next() {};
};
class Iterator
{
IteratorBase *d_base;
public:
void next() { d_base->next(); }
};