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();