我目前正在用c ++实现二叉树,我想用一个名为in_order()的函数遍历它。
有没有办法将函数作为参数传递,这样我就可以做下面的事情(不必编写代码来遍历列表多次)?
struct tree_node; // and so on
class tree; // and so on
void print_node () {
// some stuff here
}
// some other functions
tree mytree();
// insert some nodes
mytree.in_order(print_node);
mytree.in_order(push_node_to_stack);
mytree.in_order(something_else);
答案 0 :(得分:14)
是的,你可以通过多种方式实现这一目标。这有两种常见的可能性。
旧式函数指针
class mytree
{
// typedef for a function pointer to act
typedef void (*node_fn_ptr)(tree_node&);
void in_order(node_fn_ptr)
{
tree_node* pNode;
while (/* ... */)
{
// traverse...
// ... lots of code
// found node!
(*fnptr)(*pNode);
// equivalently: fnptr(*pNode)
}
}
};
void MyFunc(tree_node& tn)
{
// ...
}
void sample(mytree& tree)
{
// called with a default constructed function:
tree.inorder(&MyFunc);
// equivalently: tree.inorder(MyFunc);
}
使用仿函数
使用模板成员,使用函数指针
class mytree
{
// typedef for a function pointer to act
typedef void (*node_fn_ptr)(tree_node&);
template<class F>
void in_order(F f)
{
tree_node* pNode;
while (/* ... */)
{
// traverse...
// ... lots of code
// found node!
f(*pNode);
}
}
};
struct ExampleFunctor
{
void operator()(tree_node& node)
{
// do something with node
}
}
void sample(mytree& tree)
{
// called with a default constructed function:
tree.inorder(ExampleFunctor());
}
答案 1 :(得分:1)
是的,您可以使用函数指针作为in_order
的参数。如果传递的函数的签名不匹配,您可能还需要重载它。对于像print_node
这样的函数,像这样声明in_order(如果它的返回类型也是void
):
void tree::in_order( void (*)() )
{
//implementation
}
答案 2 :(得分:1)
我认为你应该使用访客模式。
http://en.wikipedia.org/wiki/Visitor_pattern
基本访问者类应该有一个虚拟方法来操作节点。将访问者作为参数传递给in_order方法。 然后,根据需要为您想要进行的任何操作多次派生您的访问者。