ツリーのビジター パターンに関して、コードの重複の問題に悩まされています。現在の状況は次のとおりです。2 つの異なるノード クラス、つまりリーフと非リーフで構成されるツリーがあります。さらに、1 つが const ツリーを訪問し、もう 1 つが非 const ツリーを訪問することを除いて、非常によく似た 2 つのビジター ベース クラスがあります。具体的な訪問者が実行する必要がある実際のアクションは、ノードの具体的なタイプとは無関係です。簡単な例を挙げます。
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);
}
};
具体的なビジター クラスは、そのメソッドが訪問したノードを変更する必要があるかどうかに応じて、 fromVisitor
または fromのいずれかを継承します。ConstVisitor
processNode
ご覧のとおり、2 つのビジター間で多くのコードの重複があり、const ノードと非 const ノードの両方に対して別のトラバーサル戦略を実装する必要があるため、その重複を避けたいと考えています。const_cast
できればすべての場所を使用せずに、重複したコードを抽出する可能性はありますか?