代码之家  ›  专栏  ›  技术社区  ›  Patrick Oscity

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

  •  4
  • Patrick Oscity  · 技术社区  · 16 年前

    目前我在C++中实现了一个二叉树,我想用一个名为iNoRead()的函数遍历它。

    是否有任何方法可以将函数作为参数传递,以便我可以执行以下操作(而不必编写代码来多次遍历列表)?

    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 回复  |  直到 16 年前
        1
  •  14
  •   CB Bailey    16 年前

    是的,你可以用很多方法来做到这一点。这里有两种常见的可能性。

    旧式函数指针

    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());
    }
    
        2
  •  1
  •   Zoli    16 年前

    是的,可以使用函数指针作为 in_order . 如果传递的函数的签名不匹配,您可能还需要重载它。对于类似的功能 print_node ,按如下顺序声明(前提是其返回类型为 void 同样):

    void tree::in_order( void (*)() )
    {
       //implementation
    }
    
        3
  •  1
  •   Julio    16 年前

    我认为你应该使用访客模式。

    http://en.wikipedia.org/wiki/Visitor_pattern

    基本访问者类应该有一个在节点上操作的虚拟方法。将访问者作为参数传递给in-order方法。 然后,根据您想要执行的任何操作,尽可能多次地派生您的访问者。