迭代节点层次结构 - 访问者和复合?

发布于 2024-07-13 16:40:05 字数 315 浏览 6 评论 0原文

假设我有一个节点集合,稍后将用于我的 Renderer 类。 然后我有一个可以访问节点或整个集合的 Visitor 类。 这很简单,因为我的节点集合只是 std::list 的包装器,几乎没有额外的方法。

问题是我想要一个像树一样的节点结构(而不​​是简单的列表),这样一个节点可以有一个父节点和 n 个子节点。 这会很方便,因为我希望能够将一个节点传递给我的渲染器并渲染该节点“下方”的所有内容。 答案可能是复合。

如何一起使用 Visitor 和 Composite? 我读过它通常是一个很好的组合,但我的实现看起来很糟糕......我错过了一些东西。

Let's imagine I have a collection of nodes that I use for my Renderer class later on. Then I have a Visitor class that can visit node or whole collection. It's simple because my collection of nodes it's simply a wrapper to the std::list with few extra methods.

The problem is I'd like to have a tree like structure for nodes(instead of simple list) so a node can have a parent and n children. That would be handy as I'd like to be able to pass to my Renderer a node and render everything "below" that node. The answer probably is Composite.

How can I use together Visitor and Composite? I've read that its often a good combo but my implementations look pretty bad... I'm missing sth.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绝情姑娘 2024-07-20 16:40:05

我为我们的系统实现了非常类似的东西。 我想要一种方法来组合几何对象的层次结构并将它们渲染到体积中。 我使用复合模式来撰写我的描述(根是 Node,然后派生的子节点是 compositeNode(节点列表)。CompositeNode

有方法accept(),它接受访问者(Visitor),然后在accept() 中执行访问者->; 因此,

您的访问者层次结构具有 NodeVisitor 和派生访问者,例如 RenderVisitor(渲染对象)、ReportVisitor(将节点信息转储到文本中),

所以是的, 有效,我有工作代码,但我同意设计比您在网上阅读的内容(维基或玩具示例)需要更多的努力。

组合

I have something very similar implemented for our system. I wanted a way to compose hierarchy of geometrical object and render them into the volume. I used composite pattern to compose my description (root was Node and then derived child was compositeNode (list of Nodes).

CompositeNode has method accept() which accepts a visitor (Visitor) and then inside the accept() you do visitor->visit(this).

Thus your visitor hierarchy has base class as NodeVisitor and derived visitors like RenderVisitor (renders objects), ReportVisitor (dumped node info into text). Your base class will need to accept both base and specialized node types.

So yes, combo works and I have working code but I agree that design takes more effort than what you would read online (Wiki or toy example).

Hope this helps

别闹i 2024-07-20 16:40:05

这是一个简单的例子:

struct NodeVisitor;

struct Node
{
  virtual ~Node() {}
  virtual void accept(NodeVisitor &v);
};

struct CompositeNode : public Node
{
  virtual void accept(NodeVisitor &v);
  std::list<NodePtr> nodes_;
};

struct NodeVisitor
{
  virtual ~NodeVisitor() {}
  virtual void visit(Node &n) = 0;
  virtual void visit(CompositeNode &cn)
  {
    for(std::list<NodePtr>::iterator it = cn.nodes_.begin(), end = cn.nodes_.end(); it != end; ++it)
    {
      (*it)->accept(*this);
    }
  }
};

Here's a simple example:

struct NodeVisitor;

struct Node
{
  virtual ~Node() {}
  virtual void accept(NodeVisitor &v);
};

struct CompositeNode : public Node
{
  virtual void accept(NodeVisitor &v);
  std::list<NodePtr> nodes_;
};

struct NodeVisitor
{
  virtual ~NodeVisitor() {}
  virtual void visit(Node &n) = 0;
  virtual void visit(CompositeNode &cn)
  {
    for(std::list<NodePtr>::iterator it = cn.nodes_.begin(), end = cn.nodes_.end(); it != end; ++it)
    {
      (*it)->accept(*this);
    }
  }
};
白况 2024-07-20 16:40:05

如果您希望访问者也知道树的结构(例如,访问的深度或从树根开始的路径),您可以考虑使用分层访问者模式。
c2.com wiki对此进行了较长的描述,

它还展示了如何跳过“无趣”分支。

If you want your visitor also to know the structure of the tree (e.g. the depth it is visiting or the path from the tree root) you could consider using the hierarchical visitor pattern.
This is described somewhat lengthy at c2.com wiki

It also shows how to skip an 'uninteresting' branch.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文