Я застреваю с проблемой дублирования кода, касающейся шаблона посетителя для дерева. Текущая ситуация следующая: у меня есть дерево, состоящее из двух разных классов узлов, т. Е. Листьев и нелистовых. Кроме того, у меня есть два базовых класса посетителя, которые выглядят очень похожими, за исключением того, что один посещает деревья-деревья и другие неконсольные деревья. Фактические действия, которые должны делать конкретные посетители, не зависят от конкретных типов узлов. Я дам краткий пример:Шаблон посетителя для const и nonconst версий дерева
class Visitor;
class ConstVisitor;
class Node {
public:
virtual void accept(Visitor&) = 0;
virtual void accept(ConstVisitor&) const = 0;
};
class Leaf : public Node {
virtual void accept(Visitor& v) {v.visitLeaf(*this);}
virtual void accept(ConstVisitor& cv) {cv.visitLeaf(*this);}
};
class CompoundNode : public Node {
public:
vector<Node*> getChildren() const;
virtual void accept(Visitor& v) {v.visitCompoundNode(*this);}
virtual void accept(ConstVisitor& cv) {cv.visitCompoundNode(*this);}
};
class Visitor {
protected:
virtual void processNode(Node& node) = 0;
public:
void visitLeaf(Leaf& leaf) {
processNode(leaf);
}
void visitCompoundNode(CompoundNode& cNode) {
processNode(cNode);
auto children = cNode.getChildren();
for (auto child : children)
child->accept(this);
}
};
class ConstVisitor {
protected:
virtual void processNode(Node const& node) = 0;
public:
void visitLeaf(Leaf const& leaf) {
processNode(leaf);
}
void visitCompoundNode(CompoundNode const& cNode) {
processNode(cNode);
auto children = cNode.getChildren();
for (auto child : children)
child->accept(this);
}
};
Конкретные классы наследуют посетителя либо из Visitor
или ConstVisitor
, в зависимости от того, имеет ли их метод processNode
изменять узлы посетили или нет.
Понимаете, существует много дублирования кода между двумя посетителями, и поскольку мне придется реализовать другую стратегию обхода, также как для узлов const, так и для nonconst, я хочу избежать дублирования. Есть ли возможность извлечь дубликат кода, желательно без использования const_cast
повсюду?
Спасибо, это был быстрый и чистый раствор. Я надеюсь, что мои коллеги не слишком сильно ненавижу шаблоны ;-) –
@ArneMertz: Хорошо, удачи в вашем проекте;) –