Node与NodeVisitor

来源:互联网 发布:java服务器监控系统 编辑:程序博客网 时间:2024/06/13 23:44

osg::ref_ptr< osg::Node> model;

NodeVisitor vv( TRAVERSE_ALL_CHILDREN);  

model->accept( vv);

假设model的模型结构如图:

则model->accept( vv);多态,相当于调用Group::accept(NodeVisitor)。

注意,我开始误认为Group没有对accept()进行重写,

但后来在遍历Geode结点时,发现Geode类的定义中有一个META_Node(osg, Geode),才发现这些节点都调用了META_Node宏,而

META_Node宏里有个virtual void accept(osg::NodeVisitor& nv)

{ if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); }

原来这些节点都重写accept虚函数。这样才是正确的。这个宏定义代码和voidNode::accept(NodeVisitor& nv)的实现完全相同。

 

将Group的META_Node宏中的accept展开,为:

void Group::accept(NodeVisitor& nv)

{

    if (nv.validNodeMask(*this))

    {

        nv.pushOntoNodePath(this);

        nv.apply(*this);

        nv.popFromNodePath();

    }

}

其中nv.apply(*this);因为this指针是Group*型,所以实际调用的是NodeVisitor::apply( Group& node)其中node指向Group对象

(注:如果是void Node::accept(NodeVisitor& nv){nv.apply(*this);} 则调用的不是NodeVisitor::apply( Group& node),因为nv.apply(*this)中的this参数是Node*型,

应与apply( Node*)匹配,而apply( Group*)则无法匹配,因为Node*不能隐式转换为Group*。示例程序如文章最后):

void NodeVisitor::apply(Group & node)

{

    traverse(node);

}

NodeVisitor类中

inline void traverse(Node& node)

        {

            if (_traversalMode==TRAVERSE_PARENTS) node.ascend(*this);

            else if (_traversalMode!=TRAVERSE_NONE) node.traverse(*this);

        }

由于此程序代码中NodeVisitor设置的遍历模式为TRAVERSE_ALL_CHILDREN(而不是默认的TRAVERSE_NONE),故调用Group::traverse(NodeVisitor):

void Group::traverse(NodeVisitor& nv)

{

    for(NodeList::iterator itr=_children.begin();

        itr!=_children.end();

        ++itr)

    {

        (*itr)->accept(nv);

    }

}

表示对其每一个孩子进行遍历,递归调用。相当于深搜。

附:

Node类的traverse()函数为空:

virtual void traverse(NodeVisitor& /*nv*/) {}     

递归调用过程如下图:

对以下代码:

#include "stdafx.h"

#include <iostream>

#include <string>

using namespace std;

 

class A;

class B;

 

class NodeVisitor

{

public:

    void apply( A& a)

    {

       cout<< "apply( A& a)"<< endl;     

    }

    void apply( B& b)

    {

       cout<< "apply( B& b)"<< endl;     

    }

};

 

class A

{

public:

    void accept( NodeVisitor& nv)

    {

       nv.apply( *this);//this是A*型,故调用apply( A*),即apply( A& a)

    }

};

 

class B: public A

{};

 

int _tmain(int argc, _TCHAR* argv[])

{

    B b;

    NodeVisitor nv;

    b.accept( nv);//最终调用apply( A& a)

 

    system("pause");

    return 0;

}

 

如果上述代码中实现了B的accept(),则:

#include "stdafx.h"

#include <iostream>

#include <string>

using namespace std;

 

class A;

class B;

 

class NodeVisitor

{

public:

    void apply( A& a)

    {

       cout<< "apply( A& a)"<< endl;     

    }

    void apply( B& b)

    {

       cout<< "apply( B& b)"<< endl;     

    }

};

 

class A

{

public:

    void accept( NodeVisitor& nv)

    {

       nv.apply( *this);//this是A*型,故调用apply( A*),即apply( A& a)

    }

};

 

class B: public A

{

public:

    void accept( NodeVisitor& nv)

    {

       nv.apply( *this);//this是B*型,故调用apply( B*),即apply( B& b)

    }

};

 

int _tmain(int argc, _TCHAR* argv[])

{

    B b;

    NodeVisitor nv;

    b.accept( nv);//调用B::accept(),最终调用apply( B& b)。

 

    system("pause");

    return 0;

}

 

―――――――

Visitor模型示例如下:

class Node;

class Node_derived1;

 

class NodeVisitor

{

public:

    virtual void apply( Node& n)

    {

       cout<< "NodeVisitor::apply( Node& n)"<< endl;   

    }

    virtual void apply( Node_derived1& n)

    {

       cout<< "NodeVisitor::apply( Node_derived1& n)"<< endl;     

    }

};

class NodeVisitor_Derived1: public NodeVisitor

{

public:   

virtual void apply( Node& n)//重写有关Node基类的函数

    {

       cout<< "NodeVisitor_Derived1::apply( Node& n)"<< endl;     

    }

    virtual void apply( Node_derived1& n)//写自定义的函数

    {

       cout<< "NodeVisitor_Derived1::apply( Node_derived1& n)"<< endl;      

    }

};

 

class Node

{

public:

    virtual void accept( NodeVisitor& nv)

    {

       nv.apply( *this);//this为Node*,与apply( Node*)匹配,调用apply( Node & n)

    }

};

class Node_derived1: public Node

{

public:

    virtual void accept( NodeVisitor& nv)

    {

       nv.apply( *this);//this为Node_derived1*,与apply(Node_derived1*)匹配,调用apply( Node_derived1& n)

    }

};

 

int _tmain(int argc, _TCHAR* argv[])

{  

    Node n;

    NodeVisitor nv;

    n.accept( nv);//调用NodeVisitor::apply( Node& n)

 

    Node_derived1 n1;

    NodeVisitor_Derived1 nv1;

    n1.accept( nv1);//调用NodeVisitor_Derived1::apply( Node_derived1& n)

 

    system("pause");

    return 0;

}

 

Node和NodeVisitor分别是节点基类,节点访问器基类。可以从它们继承,如Node_derived1对应NodeVisitor_Derived1。

如果想再添加Node_derived2~NodeVisitor_Derived2、Node_derived3~NodeVisitor_Derived3。但有个缺点,

就是每次除了加2个类,还需修改NodeVisitor基类,即在NodeVisitor类中加入virtualvoid apply( Node_derived_N& n)。

 

―――――――――――

OSG中的Node、Group、Geode的访问如下:

void NodeVisitor::apply(Node& node)

{

    traverse(node);

}

void NodeVisitor::apply(Group& node)

{

    traverse(node);

}

void NodeVisitor::apply(Geode& node)

{

    apply(static_cast<Node&>(node));

}

inline void NodeVisitor::traverse(Node& node)

        {

            if (_traversalMode==TRAVERSE_PARENTS) node.ascend(*this);

            else if (_traversalMode!=TRAVERSE_NONE) node.traverse(*this);

        }

 

void Node::accept(NodeVisitor& nv)

{    if (nv.validNodeMask(*this))

    {

        nv.pushOntoNodePath(this);

        nv.apply(*this);

        nv.popFromNodePath();

}}

virtual void Node::traverse(NodeVisitor& /*nv*/) {} 

 

virtual void Group::accept(osg::NodeVisitor& nv)

{ if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); }}

void Group::traverse(NodeVisitor& nv)

{

    for(NodeList::iterator itr=_children.begin();

        itr!=_children.end();

        ++itr)

    {

        (*itr)->accept(nv);

}}

 

virtual void Geode::accept(osg::NodeVisitor& nv)

{ if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); }}

 

 

 

 

原创粉丝点击