我试图使用递归遍历树,但我遇到了一个问题,因为基类是一个模板类。以下是代码:
出现问题是因为当调用RootNode traverse
函数时,它仍然对节点的所有子类使用EmptyVisitor类。但我不知道它是否有可能克服这个问题。我需要TransformNode“知道”它使用TransformVisitor而不是EmptyVisitor。我希望我能解释一下我的意思。
class BaseNode {
public:
typedef std::set<BaseNode *> ChildSet;
protected:
ChildSet mChildren;
BaseNode * mParent;
public:
BaseNode(BaseNode * parent=0) : mParent(parent) {}
~BaseNode() {}
BaseNode * addChild(BaseNode * node); //adds `node` to `mChildren`
inline BaseNode * getParent() { return mParent; }
inline const ChildSet &getChildren() const { return mChildren; }
inline ChildSet &getChildren() { return mChildren; }
};
class EmptyVisitor {
public:
static void visit(BaseNode * node) {std::cout << "Empty Visitor\n";}
};
class TransformVisitor {
static void visit(BaseNode * node) {
std::cout << "Transform Visitor\n";
}
};
template<class Visitor>
class Node : public BaseNode {
public:
void traverse() {
traverse(this);
}
void traverse(Node * node) {
Visitor::visit(this);
for(ChildSet::iterator i = node->getChildren().begin(); i != node->getChildren().end(); ++i) {
traverse(static_cast<Node*>((*i)));
}
}
};
class RootNode : public Node<EmptyVisitor> {
};
class TransformNode : public Node<TransformVisitor> {
};
的main.cpp
int main() {
RootNode * root = new RootNode;
root->addChild(new TransformNode);
root->traverse();
return 0;
}
输出:
Empty Visitor
Empty Visitor
预期产出:
Empty Visitor
Transform Visitor
答案 0 :(得分:1)
RootNode
类无法知道其他类派生自同一基类的内容。你的设计看起来有点过于模糊,与Visitor模式无关。为什么不使用普通的多态?
这只是一个草图,因为使用多态性会使您的大多数模板工作过时,因此应该进一步重构。但是,这个简单的修复方法将引导您获得所需的结果:
template<class Visitor>
class Node : public BaseNode {
public:
void traverse() {
traverse(this);
}
void traverse(Node * node) {
visit();
for(ChildSet::iterator i = node->getChildren().begin();
i != node->getChildren().end();
++i) {
traverse(static_cast<Node*>((*i)));
}
}
virtual void visit()
{
Visitor::visit(this);
}
};
class TransformNode : public Node<TransformVisitor> {
void visit()
{
TransformVisitor::visit(this);
}
};