ツリーの訪問者パターンに関して、コードの重複の問題が残っています。現在の状況は次のとおりです。私は、リーフとノンリーフの2つの異なるノードクラスからなるツリーを持っています。さらに、私は2つの訪問者基底クラスを持っていますが、それらは非常に似ていますが、constツリーと他の非constツリーを訪問する点が異なります。具体的な訪問者がしなければならない実際のアクションは、ノードの具体的なタイプとは独立しています。私は簡単な例をあげる:ツリーの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);
}
};
コンクリートビジタークラスは、そのprocessNode
方法が訪問したノードかどうかを変更することがあるかどうかに応じて、Visitor
からかConstVisitor
のいずれかから継承します。
あなたは、2人の訪問者の間でコードの重複がたくさんあることと、constノードとnonconstノードの両方に対して別のトラバーサル戦略を実装する必要があるため、重複を避けたいと思います。好ましくはconst_cast
を使用しないで、重複コードを抽出する可能性はありますか?
ありがとうございました。きれいな溶液。私は同僚があまりにも多くのテンプレートを嫌いではないと願っています;-) –
@ArneMertz:あなたのプロジェクトでは幸いです。 –