【问题标题】:How do function pointers work?函数指针是如何工作的?
【发布时间】:2011-05-30 13:15:29
【问题描述】:

我在问一些具体的问题。

  1. 如何在类中初始化它们?
  2. 如何将函数作为参数传递?
  3. 函数指针是否需要在类中声明和定义?

对于第 2 个问题,我的意思是:

void s(void) {
   //...
}

void f(function) { // what should I put as type to pass a function as an argument
   //...
}

f(s);

【问题讨论】:

    标签: c++ c pointers function-pointers


    【解决方案1】:

    要定义函数指针,请使用以下语法:

    return_type (*ref_name) (type args, ...)
    

    所以,要定义一个名为“doSomething”的函数引用,它返回一个int 并接受一个int 参数,你可以这样写:

    int (*doSomething)(int number);
    

    然后您可以像这样将引用分配给实际函数:

    int someFunction(int argument) {
       printf("%i", argument);
    }
    
    doSomething = &someFunction;
    

    完成后,您可以直接调用它:

    doSomething(5); //prints 5
    

    因为函数指针本质上只是指针,所以您确实可以将它们用作类中的实例变量。

    当接受函数指针作为参数时,我更喜欢使用typedef,而不是在函数原型中使用杂乱的语法:

    typedef int (*FunctionAcceptingAndReturningInt)(int argument);
    

    然后您可以使用这个新定义的类型作为函数的参数类型:

    void invokeFunction(int func_argument, FunctionAcceptingAndReturningInt func) {
       int result = func(func_argument);
       printf("%i", result);
    }
    
    int timesFive(int arg) {
       return arg * 5;
    }
    invokeFunction(10, &timesFive); //prints 50
    

    【讨论】:

    • 你不需要&来获取函数的地址。
    • @Luis G. Costantini R.:对于指向成员的指针,您确实需要 &(ISO 14882:2003 C++ 标准 5.3.1/3)。我个人在所有情况下都使用& 来表示我实际上是在传递一个函数指针。
    • @sil3nt:在标准库算法中
    • @sil3nt:函数指针是在与 C 兼容的公共 API 中具有回调函数的方式。然而,在 C++ 模块中,指向具有适当虚函数的抽象类的指针要灵活得多。
    • @sil3nt:在 C 语言中,可以使用函数指针来模拟在 C++ 中使用虚函数所做的事情。也就是说,您的“对象”可以是具有一组指向函数的指针的结构或数组,然后不同的“类”可以将自己的“方法”指针放入这些插槽中。另一个用途是事件驱动的“回调”类型的设计。
    【解决方案2】:

    这不是 strict 答案,但要将可配置/可分配代码包含为类成员,我会提到使用带有 operator() 的类/结构。例如:

    struct mycode
    {
        int k;
    
        mycode(int k_) : k(k_)
        {
        }
    
        int operator()(int x)
        {
         return x*k;
        }
    };
    
    
    class Foo
    {
    public : Foo(int k) : f(k) {}
    public : mycode f;
    };
    

    你可以这样做:

    Foo code(5);
    std::cout << code.f(2) << std::endl;
    

    它会打印 '10' ,我写的一切正常。

    【讨论】:

      【解决方案3】:

      你必须这样声明f

      void f(void (*x)())
      {
        x();  // call the function that you pass as parameter (Ex. s()).
      }
      

      here 是一个关于函数指针和回调的优秀教程。

      【讨论】:

        【解决方案4】:

        要回答第三个问题,您不必在类中声明它。但为了不违反封装,我通常更喜欢成员函数指针或函子,这些指针又是类的成员。上面的例子是 C 风格的函数指针,除了 Luis G. Costantini R。你可以看看this 的成员函数指针方法。 C 风格的函数指针通常被认为是,例如,回调机制,其中有一个您接收异步消息的 C 代码。在这种情况下,除了在全局范围内声明处理程序方法之外,没有其他选择。

        【讨论】:

          猜你喜欢
          • 2021-07-13
          • 2021-01-20
          • 1970-01-01
          • 2010-11-08
          相关资源
          最近更新 更多