C++ C++;子类节点上具有访问者的访问者模式丢失“;是一个;关系
首先,如果这是重复的,很抱歉。但我没有看到任何类似的情况 我对访问者模式很熟悉,我正试图在我的图表中为访问者增加一点灵活性。如果我有节点类A、B、C、SubB(继承B),我希望能够有一个访问者接受B节点,并在不知道它们的情况下自动接受SubB节点(定义accept()) 明显的好处是,我可以全天子类化,访问者不需要关心为这些类型定义访问 我有代码和结果要在下面演示。 如您所见,以下是它将访问的节点 基本上CountVisitor正确地报告它发现了2个B,我理解为什么。CountVisitor.visit(SubB&)不会被覆盖,而是会重定向到Visitor.visit(SubB&),从而跳过计数。但是,我希望它报告3(2bs+1subb)的功能,因为SubB“是一个”B。我考虑过这一点,我只是不知道如何使类型系统做到这一点。我应该如何重新安排工作以实现该功能?如果能维持“是一个”的关系,我也愿意选择其他模式,但我确实认为,如果这个障碍得到解决,访问者将是完美的C++ C++;子类节点上具有访问者的访问者模式丢失“;是一个;关系,c++,inheritance,design-patterns,visitor-pattern,C++,Inheritance,Design Patterns,Visitor Pattern,首先,如果这是重复的,很抱歉。但我没有看到任何类似的情况 我对访问者模式很熟悉,我正试图在我的图表中为访问者增加一点灵活性。如果我有节点类A、B、C、SubB(继承B),我希望能够有一个访问者接受B节点,并在不知道它们的情况下自动接受SubB节点(定义accept()) 明显的好处是,我可以全天子类化,访问者不需要关心为这些类型定义访问 我有代码和结果要在下面演示。 如您所见,以下是它将访问的节点 基本上CountVisitor正确地报告它发现了2个B,我理解为什么。CountVisitor.v
#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;
}
您可以添加一个附加层,例如:
template <typename F>
class FunctorVisitor : public Visitor
{
public:
explicit FunctorVisitor (F& f) : f(f) {}
virtual void visit(Node& n) override { f(n);}
virtual void visit(ANode& n) override { f(n);}
virtual void visit(BNode& n) override { f(n);}
virtual void visit(CNode& n) override { f(n);}
virtual void visit(SubBNode& n) override { f(n);}
private:
F& f;
};
class CountVisitor
{
public:
void operator() (const Node& n) const {
cout << __PRETTY_FUNCTION__ << "\t\tDefault" << endl;
}
void operator() (const BNode& n) {
count++;
cout << __PRETTY_FUNCTION__ << "\t\tSPECIAL" << endl;
}
int count = 0;
void print() const {
cout << "CountVisitor Found Bs: "<< count << endl;
}
};
模板
类FunctorVisitor:公共访问者
{
公众:
显式FunctorVisitor(F&F):F(F){}
虚拟无效访问(节点&n)重写{f(n);}
虚空访问(阳极&n)覆盖{f(n);}
虚拟无效访问(BNode&n)重写{f(n);}
虚拟无效访问(CNode&n)重写{f(n);}
虚拟无效访问(子节点&n)重写{f(n);}
私人:
F&F;
};
类计数访客
{
公众:
void运算符()(常量节点&n)常量{
难道你不能在你的访问者类中去掉visit(SubBNode&n)方法吗?看起来你会得到你想要的行为。是的,除非我有另一个访问者被设计成只处理SubB类型,那么它根本不可能响应那些节点。
======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
template <typename F>
class FunctorVisitor : public Visitor
{
public:
explicit FunctorVisitor (F& f) : f(f) {}
virtual void visit(Node& n) override { f(n);}
virtual void visit(ANode& n) override { f(n);}
virtual void visit(BNode& n) override { f(n);}
virtual void visit(CNode& n) override { f(n);}
virtual void visit(SubBNode& n) override { f(n);}
private:
F& f;
};
class CountVisitor
{
public:
void operator() (const Node& n) const {
cout << __PRETTY_FUNCTION__ << "\t\tDefault" << endl;
}
void operator() (const BNode& n) {
count++;
cout << __PRETTY_FUNCTION__ << "\t\tSPECIAL" << endl;
}
int count = 0;
void print() const {
cout << "CountVisitor Found Bs: "<< count << endl;
}
};