Я застрял с проблемой дублирования кода в отношении шаблона посетителя для дерева. Текущая ситуация такова: у меня есть дерево, состоящее из двух разных классов узлов, то есть листьев и не листьев. Вдобавок у меня есть два базовых класса посетителей, которые очень похожи, за исключением того, что один посещает константные деревья, а другой - неконстантные деревья. Фактические действия, которые должны выполнить конкретные посетители, не зависят от конкретных типов узла. Приведу небольшой пример:
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_cast
повсюду?