首先,对不起,如果这是重复的话。我没有看到类似的东西。
我熟悉访问者模式,并且我试图为我的图表上的访问者添加更多灵活性。如果我有节点类A,B,C,SubB(继承B),我希望能够有一个接受B节点的访问者,并且会在不知道它们的情况下自动接受SubB节点(定义accept())。 / p>
显而易见的好处是我可以整天进行子类化,并且访问者不需要关心这些类型的访问定义。
我有以下代码和结果。 如您所见,这是它将访问的节点。
new Node(), new ANode(), new BNode(), new CNode(), new BNode(), new SubBNode()
基本上,CountVisitor正确地报告它找到了2个B,我理解为什么。 CountVisitor.visit(SubB&)未被覆盖,将改为重定向到Visitor.visit(SubB&),从而跳过计数。但是,我想要报告3(2 Bs + 1 SubB)的功能,因为SubB"是" B.我已经考虑过这个问题,而我却无法弄清楚如何让类型系统做到这一点。我应该如何重新排列以实现该功能?如果能保持"是一个"我也会对替代模式持开放态度。关系,但我认为如果这个障碍得到解决,访客将是完美的。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Visitor;
class Node
{
public:
vector<Node*> children;
virtual void accept(Visitor&);
};
class ANode : public Node
{
public:
virtual void accept(Visitor&);
};
class BNode : public Node
{
public:
virtual void accept(Visitor&);
};
class CNode : public Node
{
public:
virtual void accept(Visitor&);
};
//-- try inheritance
class SubBNode: public BNode
{
public:
virtual void accept(Visitor&);
};
//--
class Visitor
{
public:
virtual void visit(Node& n);
virtual void visit(ANode& n);
virtual void visit(BNode& n);
virtual void visit(CNode& n);
virtual void visit(SubBNode& n);
};
class CountVisitor : public Visitor
{
public:
virtual void visit(BNode& n);
int count = 0;
void print();
};
//---------------------------------------------
void Node::accept(Visitor& v){
cout << __PRETTY_FUNCTION__ << endl;
v.visit(*this);
}
void ANode::accept(Visitor& v){
cout << __PRETTY_FUNCTION__ << endl;
v.visit(*this);
}
void BNode::accept(Visitor& v){
cout << __PRETTY_FUNCTION__ << endl;
v.visit(*this);
}
void CNode::accept(Visitor& v){
cout << __PRETTY_FUNCTION__ << endl;
v.visit(*this);
}
void SubBNode::accept(Visitor& v){
cout << __PRETTY_FUNCTION__ << endl;
v.visit(*this);
}
// -----
void Visitor::visit(Node& n){
cout << __PRETTY_FUNCTION__ << "\t\tDEFAULT" << endl;
}
void Visitor::visit(ANode& n){
cout << __PRETTY_FUNCTION__ << "\t\tDEFAULT" << endl;
}
void Visitor::visit(BNode& n){
cout << __PRETTY_FUNCTION__ << "\t\tDEFAULT" << endl;
}
void Visitor::visit(CNode& n){
cout << __PRETTY_FUNCTION__ << "\t\tDEFAULT" << endl;
}
void Visitor::visit(SubBNode& n){
cout << __PRETTY_FUNCTION__ << "\t\tDEFAULT" << endl;
}
// -----
void CountVisitor::visit(BNode& n){
count++;
cout << __PRETTY_FUNCTION__ << "\t\tSPECIAL" << endl;
}
void CountVisitor::print(){
cout << "CountVisitor Found Bs: "<< count << endl;
}
// ====================================================
int main() {
cout << "======FLAT TEST======" << endl;
vector<Node*> nodes = {
new Node(),
new ANode(),
new BNode(),
new CNode(),
new BNode(),
new SubBNode()
};
cout << "--DEFAULT--" << endl;
Visitor v1;
for( Node* n : nodes ){
n->accept(v1);
}
cout << "--COUNT--" << endl;
CountVisitor cv1;
for( Node* n : nodes ){
n->accept(cv1);
}
cv1.print();
return 0;
}
结果
======FLAT TEST======
--DEFAULT--
virtual void Node::accept(Visitor&)
virtual void Visitor::visit(Node&) DEFAULT
virtual void ANode::accept(Visitor&)
virtual void Visitor::visit(ANode&) DEFAULT
virtual void BNode::accept(Visitor&)
virtual void Visitor::visit(BNode&) DEFAULT
virtual void CNode::accept(Visitor&)
virtual void Visitor::visit(CNode&) DEFAULT
virtual void BNode::accept(Visitor&)
virtual void Visitor::visit(BNode&) DEFAULT
virtual void SubBNode::accept(Visitor&)
virtual void Visitor::visit(SubBNode&) DEFAULT
--COUNT--
virtual void Node::accept(Visitor&)
virtual void Visitor::visit(Node&) DEFAULT
virtual void ANode::accept(Visitor&)
virtual void Visitor::visit(ANode&) DEFAULT
virtual void BNode::accept(Visitor&)
virtual void CountVisitor::visit(BNode&) SPECIAL
virtual void CNode::accept(Visitor&)
virtual void Visitor::visit(CNode&) DEFAULT
virtual void BNode::accept(Visitor&)
virtual void CountVisitor::visit(BNode&) SPECIAL
virtual void SubBNode::accept(Visitor&)
virtual void Visitor::visit(SubBNode&) DEFAULT
CountVisitor Found Bs: 2