【问题标题】:C++ Avoiding Circular Dependencies with a TreeC++ 使用树避免循环依赖
【发布时间】:2011-10-29 12:19:05
【问题描述】:

我正在编写一个树结构,我想将不同的数据存储在叶节点到分支节点中。这个想法与动态编程方法非常相似——聚合数据存储在分支中。因此我想出了(为简单起见减少了)

template<class L, class B> class node {
public:
    virtual ~node() {}
    // [...] visitor stuff
};

template<class L, class B> class branch : public node<L,B> {
public:
    template<class It>
    branch(It b, It e) {
        // Do something with the iterators;
        // decide if to create branches or leaves

        // Create the branch data
        b_ = new B(/* Unknown */);
    }
    ~branch() { delete b_; delete child_[0]; delete child_[1]; }

private:
    B* b_;  node<L,B>* child_[2];
};

template<class L, class B> class leaf : public node<L,B> {
public:
    leaf(L* l) : l_(l) {}
    ~leaf() {}

private:
    L* l_;
};

LB 结构为例

struct myleaf   { int x; };
struct mybranch {
    mybranch(/* Unknown */) {
    // Apply a visitor to the child nodes to get sumx
    }
    int sumx;
    // Some other properties
};

我的问题是如何在不遇到 B 的循环依赖的情况下做到这一点,具体取决于 node&lt;L,B&gt;。或者,我可以轻松地重新构建代码以完全避免这个问题吗?

【问题讨论】:

  • 公共继承模型“is-a”。因此,您说分支是节点。我认为这是您设计中非常基本的问题,它使它变得复杂。

标签: c++ templates tree circular-dependency


【解决方案1】:

据我所知,没有问题。

它基本上是 CRTP 的一个示例,这是 C++ 模板代码中相当常见的模式。

当然,你可以让编译器跳起来,所以这不起作用,但在基本层面上,class Derived : Base&lt;Derived&gt; 形式的依赖关系没有任何问题

【讨论】:

    【解决方案2】:

    我认为您正试图让branch 处理遍历树并获得价值。让访问者绕着树走的责任应该在树结构中,打破与结构的依赖关系。当访问者应用于叶子节点时,它将应用它设计的任何操作,当应用于分支时,它可以更新值并执行操作。

    为了能够有效地实现这一点,您可能需要向分支/节点内部类型添加一个接口,以提供该值是否已被预缓存的信息(即无需遍历树)

    【讨论】:

      猜你喜欢
      • 2013-02-06
      • 1970-01-01
      • 2012-02-15
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多