C++函数指针的用法

4

我是一个C++的新手,最近在学习函数指针,对于函数指针的使用还有些困惑;

我练习了以下代码:

#include <iostream>
#include <sstream>
using namespace std;

int subtraction(int a,int b){
    return a-b;
}

int main(int argc, const char * argv[])
{

    int (*minus)(int,int)=subtraction;
    cout<<minus(5,4);

    return 0;
}

它很好用;因此,我尝试了一点变化:

#include <iostream>
#include <sstream>
using namespace std;

int subtraction(int a,int b){
    return a-b;
}

int main(int argc, const char * argv[])
{

    int *minus(int,int)=subtraction;//only here different!
    cout<<minus(5,4);

    return 0;
}

我在Mac上的Xcode中练习它,结果出现了错误:

非法初始化程序(只有变量可以被初始化)

但是我认为编译器可以识别这两个是相同的,为什么一定要有一对括号呢?


1
同样的原因 int* minus(int,int)=subtraction; 不起作用。 - David Schwartz
3
他正在学习C++。了解它至少是有用的。 - Siyuan Ren
@C.R. - C++ 的整个重点是面向对象编程,而不是函数式的。 - Ed Heal
3
a) 在这个语境下,我认为“函子”更直接地可与函数指针进行比较,而最接近面向对象编程的是“命令模式”。 b) C++ 是一种多范式语言,包括函数式编程(这与使用函数指针完全相同)。 - Maciej Piechotka
6
我从未听过Bjarne Stroustrup说过C++首先和主要是一种面向对象编程语言。C++的整个设计目的是多范式的。在某些情况下,函数式编程是最好的解决方案,并且它也可以在C++中实现,因此学习如何使用它是有益的。只需看看C++11中lambda表达式的成功,便可知道这一点。 - Marc Claesen
显示剩余3条评论
3个回答

9
在你的原始代码中
int (*minus)(int,int)=subtraction;

声明minus为一个以int, int作为参数并返回int函数指针

在你的第二段代码中:

int *minus(int,int)=subtraction;

声明minus为一个函数,该函数带有参数int, int并返回指向int *的指针。

您可以使用函数名称(自动转换为函数指针)初始化函数指针,但不能初始化函数本身。


如果我没记错的话,函数名不严格地说是一个指针,因为它具有函数类型,但它会自动转换为函数指针(就像数组和指针一样)。请考虑 int (*minus)(int,int) = &subtraction; 也是有效的。 - Maciej Piechotka
@MaciejPiechotka 这更加精确,我会修改我的措辞,谢谢。 - Yu Hao

3
这是一个关于运算符优先级的问题。函数调用运算符()比解引用运算符*具有更高的优先级。因此,您必须使用括号来指定正确的评估顺序。
int *minus(int, int)

意思是:首先调用一个名为“minus”的函数,然后对返回值进行解引用(在本例中为int*)。
int (*minus)(int, int)

意思是:首先解引用“减号”,返回一个函数,然后调用该函数。

3

您已经标记了代码C++并使用了iostream,因此我可以安全地假设您正在寻找一种C++解决方案。

在这种情况下,最好使用类模板std::function而不是容易出错的函数指针语法。

#include <iostream>
#include <sstream>
#include <functional>


int subtraction(int a,int b){
    return a-b;
}

int main(int argc, const char * argv[])
{
    std::function<int(int,int)> minus = subtraction;
    //int (*minus)(int,int)=subtraction;
    std::cout<<minus(5,4);

    return 0;
}

如果您仍然想继续使用函数指针,建议使用typedefs。

#include <iostream>
int subtraction(int a,int b){
    return a-b;
}
typedef int (*MINUS)(int,int);
int main(int argc, const char * argv[])
{
    MINUS minus = subtraction;
    //int (*minus)(int,int)=subtraction;
    std::cout<<minus(5,4);

    return 0;
}

最后,另一个广泛使用的选项是使用函数对象。
#include <iostream>
struct MINUS
{
    int operator()(int a,int b){
        return a-b;
    }
};
int main(int argc, const char * argv[])
{
    //int (*minus)(int,int)=subtraction;
    MINUS minus;
    std::cout<<minus(5,4);

    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接