Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;子类节点上具有访问者的访问者模式丢失“;是一个;关系_C++_Inheritance_Design Patterns_Visitor Pattern - Fatal编程技术网

C++ C++;子类节点上具有访问者的访问者模式丢失“;是一个;关系

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

首先,如果这是重复的,很抱歉。但我没有看到任何类似的情况

我对访问者模式很熟悉,我正试图在我的图表中为访问者增加一点灵活性。如果我有节点类A、B、C、SubB(继承B),我希望能够有一个访问者接受B节点,并在不知道它们的情况下自动接受SubB节点(定义accept())

明显的好处是,我可以全天子类化,访问者不需要关心为这些类型定义访问

我有代码和结果要在下面演示。 如您所见,以下是它将访问的节点

基本上CountVisitor正确地报告它发现了2个B,我理解为什么。CountVisitor.visit(SubB&)不会被覆盖,而是会重定向到Visitor.visit(SubB&),从而跳过计数。但是,我希望它报告3(2bs+1subb)的功能,因为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;
}

您可以添加一个附加层,例如:

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;
    }
};