如何迭代另一个类中的容器?
我已经遇到过这个问题几次,想知道是否有一个简单的方法或模式可以用来解决它。
想象一个树结构,其中每个节点都包含一个指向子节点的指针的 STL 容器(向量)。我希望客户端代码能够遍历这棵树,并迭代子容器以访问其他部分。
我的问题是,我想维护节点的封装,同时让客户端轻松查看该节点的所有子节点。我还想确保,如果客户端获得对树中根节点的常量引用,那么对树的后续部分的所有访问也是常量的。
我应该尝试为我的节点类型创建一个迭代器类,让节点方法返回向量迭代器,还是我缺少更优雅的模式?
编辑:我想再次强调,虽然我看到了一些好的想法,但我有指向其他节点的指针容器。返回 vector
不会阻止客户端调用节点上的非常量方法。它仅保护指针本身不指向不同的对象。
I've come across this issue a few times and would like find out if there is a simple method or pattern I can use to solve it.
Imagine a tree structure where each node contains a STL container (vector) of pointers to children. I want client code to be able to traverse this tree, and iterate through the child containers to access other parts.
My problem is that I want to maintain encapsulation for my nodes while at the same time letting clients easily see all of the children for that node. I also want to make sure that if a client gets a const reference to the root node in the tree, then all access to subsequent parts of the tree are also const.
Should I try to make an iterator class for my node type, have a node method return vector iterators , or is there a more elegant pattern I'm missing?
Edit: I want to stress again that while I see some good ideas presented, I have containers of pointers to other nodes. Returning a vector<node *>::const_iterator
will not prevent clients from calling non-const methods on the node. It only protects the pointers themselves from pointing at different objects.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
像这样的东西通常就足够了:
这允许您更改底层容器类型,而无需更改迭代
节点
子节点的代码。这样做的缺点是它会泄漏实现细节,因为使用
node::const_iterator
的代码知道它是一个随机访问迭代器(因为std::vector:: const_iterator
> 是一个随机访问迭代器),因此您可能很难切换到不支持随机访问的容器。如果您希望能够自己控制迭代器类别,您可能需要创建自己的迭代器类来提供您想要提供的确切行为。
Something like this is usually sufficient:
This allows you to change the underlying container type without changing code that iterates over a
node
's children.This does have the disadvantage that it leaks an implementation detail because code that uses your
node::const_iterator
know that it is a random access iterator (becausestd::vector:: const_iterator
is a random access iterator), so you might have a hard time switching to a container that didn't support random access.If you want to be able to control the iterator category yourself, you'll probably want to create your own
iterator
class that provides the exact behavior you want to provide.这不是对您问题的直接答案,而是一种替代方法。您可以通过注册回调函子来控制反转,而不是让客户端代码运行该节目。例如:
完成封装!
This isn't a direct answer to your question, but rather, an alternative approach. Rather than have the client code run the show, you could go for control inversion by registering a callback functor. For instance:
Complete encaspulation achieved!
为了遍历整个树,您必须创建自己的迭代器类,对于仅遍历子树,您可以安全地返回向量迭代器。
For traversing the entire tree, you would have to create your own iterator class, for just traversing the children, you can safely return the vector iterators.