嗨,我正在尝试学习C/C++中的一些函数指针,并试图在Ubuntu上用gcc编写以下C++代码。
此代码应根据编译期间提供的预处理器标志-DAD或-DMULTIPLY
#include <iostream>
#include <iomanip>
//Adds two numbers
int add(int a, int b)
{
return a+b;
}
//Multiplies two numbers
int multiply(int a, int b)
{
return a*b;
}
//Function to set the correct function to be executed.
//All functions here should have the same signature.
void functionsetter( void (*ptr2fun)(int,int) )
{
#ifdef ADD
ptr2fun = add;
#endif
#ifdef MULTIPLY
ptr2fun = multiply
#endif
}
int main(int argc, char *argv[])
{
int a = 5;
int b = 6;
void (*foo)(int,int);
functionsetter(foo);
return 0;
}
我不知道如何通过引用将函数指针foo
传递给function-setter
函数。有人能帮我一下吗。我确信的声明
functionsetter
在代码中有错误,请让我知道如何修复。
我正在尝试用g++ -O2 -g -Wall -DADD main.cpp -o main
编译这个
注意:我想在其他代码中使用这样的预处理器标志和函数指针。请告诉我这样做是否是个好主意/好做法。
如果不使用typedef
,引用函数指针的语法为:
void functionsetter(void (*&ptr2fun)(int, int)) { ... }
但通常为指针类型创建typedef
更简单:
typedef void (*FunctionPointer)(int, int);
void functionsetter(FunctionPointer& ptr2fun) { ... }
或者对于功能类型:
typedef void Function(int, int);
void functionsetter(Function*& ptr2fun) { ... }
使用typedef
:
typedef void (*MyFunctionPointer)(int,int);
void functionsetter(MyFunctionPointer& fp);
我想在其他代码中使用这样的预处理器标志和函数指针。请告诉我这样做是否是个好主意/好做法。
不,不是真的。从您的示例中还不清楚您试图实现什么,但您的实现相当不寻常。考虑使用虚拟成员函数或std::function
在运行时切换函数实现,或者(可能)使用模板在编译时切换它们。像这样使用条件编译进行静态选择没有错,但将其与函数指针混合使用有点奇怪。
如果对你试图解决的问题没有很好的理解,就很难就如何最好地解决它给出好的建议。
您可以将签名更改为:
void functionsetter( void (*&ptr2fun)(int,int) )
请注意,ptr2fun函数指针的签名错误,加法和乘法函数返回int,ptr2fun
也应该返回int
如果你使用typedef:,这会变得容易得多
typedef int (*ptr2fun)(int,int);
void functionsetter(ptr2fun& func) { ...
不过,就我个人而言,我只会返回函数指针。
ptr2fun functionsetter()
{
#ifdef ADD
return add;
#endif
#ifdef MULTIPLY
return multiply
#endif
}
首先,您没有将函数指针引用传递给方法,您只是传递了一个函数指针。您需要将方法签名更改为
void functionsetter( void (*&ptr2fun)(int,int) )
此外,您的方法签名在某些地方是void(*)(int,int)
,在某些地方则是int(*)(int,int)
,它们可能在任何地方都是后者,因为您的加法和乘法方法返回int
。
也就是说,由于您使用的是C++,因此我不建议以这种方式操作指针,C++具有继承/虚拟方法,通常可以取代大多数函数指针的使用,并使代码更具可读性和可扩展性。