【发布时间】:2020-04-08 20:23:08
【问题描述】:
我想要一个类接口(我们称之为A类),它可以在我的代码中以不同的方式继承和实现,并且该接口包含一些函数,包括一个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 上实现,另一个直接在文件上实现。这意味着向量存储库的迭代器必须只给我 const std::vector 迭代器,而另一个必须以只读方式打开文件、转到下一行等。我必须使它们与基于范围的 for 循环兼容。
【问题讨论】:
-
很抱歉。我取消了评论,因为我不确定我是否理解这个问题,而且我的替换评论需要很长时间才能写出来。
-
没关系。我的 B::iterator 是在一个 cpp 文件中实现的,与这个头文件分开。但这不重要,问题是程序说 B::begin() 和 B::end() 不返回与 A::begin() 和 A::end() 相同的类型,这是正确的,因为在 A 中我返回一个 A::iterator,而在 B 中我返回一个 B::iterator。但是 B::iterator 继承自 A::iterator,这也使它成为 A::iterator,所以我不知道问题是什么以及为什么它不想这样编译它。
-
您希望
A的所有子级都实现一个迭代器。你已经做到了。所有子迭代器都可以不同,但仍将支持A::iterator定义的通用接口。我们这里有一个X-Y problem。你有一个解决问题的方法,这个问题正在制造更多的问题。您最好修改问题以询问您尝试使用此解决方案解决的问题。 -
做了编辑,很抱歉不清楚我想要实现的目标。
-
由于 is-a 关系,您可以使用对
B::iterator到A::iterator的引用,但这很奇怪。迭代器应该像那样掩盖蓝精灵。如果添加另一层抽象会怎样?在这种情况下,A::iterator并不是真正的迭代器。它是一个包装器,它隐藏了它持有对B::iterator(或任何实现A::private_iterator接口的任何东西)的引用这一事实。
标签: c++ inheritance polymorphism inner-classes