Utknąłem z problemem powielania kodu, w odniesieniu do wzorca odwiedzającego dla drzewa. Obecna sytuacja wygląda następująco: Mam drzewo, składające się z dwóch różnych klas węzłów, tj. Liści i nie-liści. Ponadto mam dwie klasy baz danych odwiedzających, które wyglądają bardzo podobnie, oprócz tego, że odwiedza się drzewa const i inne niestanowiące drzewa. Rzeczywiste działania, które muszą wykonać konkretni goście, są niezależne od konkretnych typów węzłów. Podam krótki przykład:Wzorce odwiedzin dla stałych i niepasujących wersji drzewa
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);
}
};
zajęcia gości betonowe odziedziczyć albo z Visitor
lub ConstVisitor
, w zależności od tego, czy ich metoda processNode
musi zmieniać węzły odwiedził czy nie.
Widzisz, istnieje wiele powielania kodu między dwoma odwiedzającymi i ponieważ będę musiał wdrożyć inną strategię przejścia, także dla węzłów stałych i stałych, chcę uniknąć tego duplikowania. Czy są jakieś możliwości wyodrębnienia duplikatu kodu, najlepiej bez używania const_cast
w każdym miejscu?
Dzięki, to był szybki i czyste rozwiązanie. Mam nadzieję, że moi koledzy nie nienawidzą szablonów zbyt wiele ;-) –
@ArneMertz: W porządku, powodzenia w projekcie;) –