(这个问题以前可能已经回答过了,我可以找到类似的问题,但没有任何东西可以适用于我的情况。当然,欢迎提供相关问题的链接。
以下是我正在尝试做的事情的说明:
#include <vector>
class Abstract
{
public:
virtual std::vector<Abstract *> children() = 0;
};
class Concrete : public Abstract
{
public:
std::vector<Abstract *> children() override {return std::vector<Abstract *>();}
/* This returns an empty vector. What should actually go here, to return the actual children? */
private:
std::vector<Concrete *> m_children;
};
void doSomething(Abstract *a)
{
}
int main()
{
Concrete c;
for(auto& object : c.children())
doSomething(object);
}
换句话说,我的 Concrete 对象将自己的类实例作为子对象。其他代码希望将它们视为其抽象基类。我可以想到一些方法来实现这一目标,但我正在努力找到一个优雅的方法。如果我的类支持迭代,那就太好了,但我无法让它与虚拟抽象函数一起使用。我试过这个:
(摘要)
virtual std::vector<const Abstract *>::const_iterator begin() const = 0;
virtual std::vector<const Abstract *>::const_iterator end() const = 0;
virtual std::vector<Abstract *>::iterator begin() = 0;
virtual std::vector<Abstract *>::iterator end() = 0;
,但是我在 Concrete::begin() 中做什么(其中m_子项声明为
m_children std::vector<Concrete *>
)?我这样开始:
std::vector<const Abstract *>::const_iterator it;
Abstract *first = *m_children.begin();
。认为我可以让"it"指向我的向量中的第一个实例。这就是我被难倒的地方。
建议赞赏!
在 C++11 中,
return { begin(vec), end(vec) };
将具体指针的 vec 转换为抽象向量。 就是这么简单。
在 C++03 中,您必须显式调用构造函数并使用 .begin
而不是 free 函数。
可以通过 boost 或手动编写将迭代器带到具体并生成迭代器到抽象的转换迭代器,然后重新编写一系列所述迭代器。
类型擦除迭代器,使它们只是"abstract*
的通用迭代器"可以完成,无论是有提升还是没有。 这会增加开销(如果不小心处理,可能会很大),并且只有在上述两个选项被证明有问题时才应该考虑,并且这在实际测试中被证明可以解决问题。