Я хочу иметь интерфейс класса (назовем его классом А), который может наследоваться и реализовываться по-разному в моем коде, и этот интерфейс содержит некоторые функции, включая итератор типа stl, который определяется как вложенный класс.
Моя проблема в том, что всякий раз, когда я пытаюсь унаследовать интерфейс (в класс давайте вызовем B), а также итератор и реализовать их, начало и конец унаследованного класса ожидают итератор типа A :: iterator, хотя итератор в классе B наследуется от A :: iterator. Я знаю, что полиморфизм работает только с указателями / ссылками, но как я смогу это сделать?
Я также пытался делать это с классами друзей, но я не очень хорошо знаю, как они работают, как я никогда не использовал их раньше, так получилось немного грязно. Вот пример кода (который я действительно запускаю)
class A
{
public:
class iterator
{
public:
virtual Entity& operator*() const = 0;
virtual bool operator!=(const iterator) const = 0;
virtual bool valid() const = 0;
virtual iterator& operator=(const iterator& it) = 0;
virtual iterator operator++() = 0;
virtual iterator operator++(int) = 0;
virtual ~iterator() {};
};
virtual int add(const std::vector<std::string>& params) = 0;
virtual int remove(const std::vector<std::string>& params) = 0;
virtual int update(const std::vector<std::string>& params) = 0;
virtual int save(const std::vector<std::string>& params) = 0;
virtual int size() = 0;
virtual typename iterator begin() = 0;
virtual typename iterator end() = 0;
virtual ~A() {}
};
class B: public A
{
private:
std::vector<Entity> elements;
public:
class iterator : public A::iterator
{
private:
std::vector<Entity>::iterator ptr;
B& repo;
public:
iterator(std::vector<Entity>::iterator ptr, B& container) : ptr{ ptr }, repo{ container }{}
Entity& operator*() const override;
bool operator!=(const iterator) const override;
bool valid() const override;
iterator& operator=(const iterator& it) override;
iterator operator++() override;
iterator operator++(int) override;
};
B() : elements{ std::vector<Entity>() } {}
int add(const std::vector<std::string>& params) override;
int remove(const std::vector<std::string>& params) override;
int update(const std::vector<std::string>& params) override;
int save(const std::vector<std::string>& params) override;
int size() override;
typename iterator begin();
typename iterator end();
~B() {};
};
Причина, по которой я хочу это сделать, заключается в том, что мне нужно создать 2 разных репозитория, один из которых работает с файлом, а другой - в памяти, и возможно, в будущем потребуется база данных, но я просто не могу получить правильный итератор, унаследовав его. Возвращение std :: vector будет намного быстрее, но также и обманом. РЕДАКТИРОВАТЬ: То, что я в конечном итоге пытаюсь достичь, - это иметь два репозитория с одинаковым интерфейсом, которые также можно перебирать, один из которых реализован на std :: vector, а другой - непосредственно в файле. Это означает, что итератор для векторного репозитория должен будет просто дать мне константный std :: vector итератор, а другой должен открыть файл, go до следующей строки и т. Д. c только для чтения , Я должен сделать их совместимыми с диапазоном, основанным на l oop.