模仿OSG的NodeVisitor机制实现简易访问者模式(Visitor Pattern)
Node.h
#pragma once
#include <iostream>
#include <vector>
#include "NodeVisitor.h"
#include "NodeCallback.h"
class NodeVisitor;
class Node
{
public:
Node();
Node(int);
~Node();
public:
void addChild(Node*);
void show();
public:
//接收一个访问器,并执行访问器的apply函数(将自身传入nv.apply()),
//nv的apply函数中执行具体的访问操作
void accept(NodeVisitor& nv);
//向下一级节点推进访问器
void traverse(NodeVisitor& nv);
public:
void setCallback(NodeCallback*);
NodeCallback* getCallback();
protected:
int _num;
std::vector<Node*> _children;
NodeCallback* _callback;
};
Node.cpp
#include "Node.h"
Node::Node()
{
}
Node::Node(int num) : _num(num)
{
}
Node::~Node()
{
}
void Node::addChild(Node* child)
{
_children.push_back(child);
}
void Node::show()
{
std::cout << _num << std::endl;
}
void Node::accept(NodeVisitor & nv)
{
nv.apply(*this);
}
void Node::traverse(NodeVisitor & nv)
{
for (auto child = _children.begin(); child != _children.end(); child++)
{
(*child)->accept(nv);
}
}
NodeVisitor.h
#pragma once
#include "Node.h"
class Node;
class NodeVisitor
{
public:
NodeVisitor();
~NodeVisitor();
public:
//向下一个要访问的节点推进
void traverse(Node& node);
//访问节点,并执行访问器中自定义的节点操作
void apply(Node& node);
};
NodeVisitor.cpp
#include "NodeVisitor.h"
NodeVisitor::NodeVisitor()
{
}
NodeVisitor::~NodeVisitor()
{
}
void NodeVisitor::traverse(Node& node)
{
node.traverse(*this);
}
void NodeVisitor::apply(Node& node)
{
node.show(); //自定义行为
traverse(node);
}
#include "NodeVisitor.h"
NodeVisitor::NodeVisitor()
{
}
NodeVisitor::~NodeVisitor()
{
}
void NodeVisitor::traverse(Node& node)
{
node.traverse(*this);
}
void NodeVisitor::apply(Node& node)
{
node.show(); //自定义行为
traverse(node);
}
main.cpp
#include "Node.h"
#include "NodeVisitor.h"
#include <iostream>
#include <vector>
int main()
{
std::vector<Node> nodes;
for (int i = 1; i <= 5; i++)
{
nodes.push_back(Node(i));
}
nodes[0].addChild(&nodes[1]);
nodes[0].addChild(&nodes[2]);
nodes[1].addChild(&nodes[3]);
nodes[1].addChild(&nodes[4]);
NodeVisitor nv;
nodes[0].accept(nv);
system("pause");
return 0;
}
节点树:
DFS结果:1、2、4、5、3
访问者模式(访问器模式、Visitor Pattern)流程:
- 待访问节点node接收一个访问器nv
NodeVisitor nv;
node.accept(nv);
- nv访问该节点
nv.apply(*this);
void NodeVisitor::apply(Node & node)
{
/********用户自定义对节点的操作*******/
node.show();
/*************************************/
traverse(node);//推进到下一个节点
}
- 操作完成后,nv访问继续下一个节点
traverse(node);//推进到下一个节点
void NodeVisitor::traverse(Node& node)
{
node.traverse(*this);
}
nv的traverse直接调用节点的traverse方法,推进到下一个节点(子节点、父节点等)
void Node::traverse(NodeVisitor & nv)
{
for (auto child = _children.begin(); child != _children.end(); child++)
{
(*child)->accept(nv);
}
}