c ++:将函数作为参数传递给另一个函数

时间:2009-11-04 11:53:27

标签: c++ tree traversal

我目前正在用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);

3 个答案:

答案 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方法。 然后,根据需要为您想要进行的任何操作多次派生您的访问者。