C ++ Избегание циклических зависимостей с помощью дерева - PullRequest
0 голосов
/ 29 октября 2011

Я пишу древовидную структуру, в которой я хочу хранить различные данные в конечных узлах для узлов ветвления.Идея очень похожа на метод динамического программирования - совокупные данные хранятся в ветвях.Поэтому я придумал (сокращен для простоты)

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_;
};

. Например, L и B структуры:

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 ]

1 голос
/ 29 октября 2011

Насколько я вижу, проблем нет.

Это в основном пример CRTP , довольно распространенный шаблон для кода шаблона в C ++.

Конечно, вы можете отключить компилятор, чтобы он не работал, но на базовом уровне нет ничего плохого в зависимостях вида class Derived : Base<Derived>

0 голосов
/ 29 октября 2011

Я думаю, что вы пытаетесь заключить сделку branch с ходьбой по дереву и получением значения. Ответственность за обход посетителя должна быть в структуре дерева, нарушая зависимость от структуры. Когда посетитель применяется к конечным узлам, он будет применять любую операцию, для которой он предназначен, при применении к ветвям он может как обновлять значение, так и выполнять операцию.

Чтобы реализовать это эффективно, вам может потребоваться добавить интерфейс к внутренним типам ветвей / узлов, чтобы предоставить информацию о том, является ли значение уже предварительно кэшированным (то есть нет необходимости переходить по дереву)

...