C ++避免使用树的循环依赖

时间:2011-10-29 12:19:05

标签: c++ templates tree circular-dependency

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

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<L,B>。或者,我可以轻松地重新构建代码以完全避免这个问题吗?

2 个答案:

答案 0 :(得分:1)

据我所见,没有问题。

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

当然你可以绊倒编译器,这样就行不通了,但在基础层面,class Derived : Base<Derived>

形式的依赖关系没有错

答案 1 :(得分:0)

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

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