C++ 传递函数指针
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19417826/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing Function Pointer
提问by ThePedestrian
I'm a bit confused as to how I would pass a pointer to a pointer function. I have a function that takes a pointer to a function which I understand without problem (ExecBlock). But I'm given another prototype of a function (ExecBlock2) which takes the dereferenced-pointer (I'm not sure exactly what it is) and also takes the argument if passed function has any. If someone could explain the precedence and exactly what dereferencing a pointer function would do. Isn't that just passing the function itself?. What does (void *) do in this case?
我对如何将指针传递给指针函数有点困惑。我有一个函数,它带有一个指向我理解的函数的指针(ExecBlock)。但是我得到了另一个函数原型(ExecBlock2),它接受解引用指针(我不确定它到底是什么)并且如果传递的函数有任何参数,也接受参数。如果有人可以解释优先级以及取消引用指针函数会做什么。这不就是传递函数本身吗?在这种情况下 (void *) 做什么?
int ExecBlock (void (*f) (void), int isSet)
{
return ExecBlock2( HOW TO PASS HERE? , NULL, isSet);
}
int ExecBlock2(void *(*f)(void *), void *arg, int isSet)
{
... more code
}
回答by Chris Rice
void (*f) (void)
means pointer to function with no arguments returning void.
表示指向函数的指针,没有返回 void 的参数。
void *(*f)(void *)
means pointer to function taking a void pointer and returning a void pointer.
表示函数指针采用 void 指针并返回 void 指针。
Since the types are different, the compiler will not allow you to pass one to the other without casting. (Note that casting is not really the right answer here, and as @detly points out, results in undefined behavior.)
由于类型不同,编译器将不允许您在不进行强制转换的情况下将一个传递给另一个。(请注意,这里的强制转换并不是真正的正确答案,正如@detly 指出的那样,会导致未定义的行为。)
As for dereferencing pointers to functions, you don't have to explicitly put a "*" before a function pointer to call it. For instance, you could call your function pointer f just by doing
至于取消对函数的指针的引用,您不必在函数指针之前显式地放置“*”来调用它。例如,您可以通过执行以下操作来调用函数指针 f
f();
A function pointer example
函数指针示例
Say you have a function f
, which you'd like to pass to a function called takes_a_function
.
takes_a_function
will probably have a type like
假设您有一个 function f
,您希望将其传递给名为 的函数takes_a_function
。
takes_a_function
可能会有类似的类型
void takes_a_function(void (*f)(void *data), void *data);
Notice how there are two arguments to takes_a_function
, a function pointer, and a void pointer to some data. Also note that the function f
happens to take a void pointer as an argument. The idea is that you can pass the data to takes_a_function
, and it will pass it along to f
. For example, takes_a_function
could be defined like
注意 有两个参数takes_a_function
,一个函数指针和一个指向某些数据的空指针。另请注意,该函数f
恰好将 void 指针作为参数。这个想法是,您可以将数据传递给takes_a_function
,它会将其传递给f
。例如,takes_a_function
可以定义为
void takes_a_function(void (*f)(void *), void *data) {
f(data);
}
Now, let's write a function to pass to takes_a_function
. Our function will just print an int that is passed to it.
现在,让我们编写一个函数来传递给takes_a_function
. 我们的函数将只打印一个传递给它的 int。
void prints_an_int(void *data) {
// The idiom for converting a void pointer to another kind
// of pointer. NO NEED TO CAST. Note this behavior is only
// defined if the pointer data really does point to an int.
int *i = data;
printf("%d", *i);
}
int i = 0;
takes_a_function(prints_an_int, &i);
A couple of key points about this example:
关于这个例子的几个关键点:
prints_an_int
has the same type as the function pointer expected bytakes_a_function
. No need to cast.- There's no need to use the
&
operator to create a reference to a function. This is why we can passprints_an_int
totakes_a_function
directly. But we could also saytakes_a_function(&prints_an_int, &i)
, and it would be the same. void*
basically means "pointer to unknown type." To actually do anything with it, you must assign a variable of typevoid*
to another pointer variable whose type you expect. This is only guaranteed to work if you actually pass in the correct pointer type! In this example, we can assigndata
to anint*
, since data really does point to an int. If you want more data than just an integer, a common pattern is to create your own struct type which includes all the fields you want, and pass that instead.- As a special case, the compiler does not require you to cast when assigning void pointers to other pointers and vice-versa. But again, you only get defined behavior if you eventually convert a void pointer back to the correct type.
prints_an_int
具有与 期望的函数指针相同的类型takes_a_function
。没必要投。- 无需使用
&
运算符来创建对函数的引用。这就是为什么我们可以直接传递prints_an_int
给takes_a_function
。但我们也可以说takes_a_function(&prints_an_int, &i)
,它会是一样的。 void*
基本上意味着“指向未知类型的指针”。要实际使用它做任何事情,您必须将一个类型的变量分配void*
给另一个您期望类型的指针变量。这只有在您实际传入正确的指针类型时才能保证工作!在这个例子中,我们可以分配data
给 anint*
,因为 data 确实指向一个 int。如果你想要更多的数据而不仅仅是一个整数,一个常见的模式是创建你自己的结构类型,其中包含你想要的所有字段,然后传递它。- 作为一种特殊情况,编译器在将 void 指针分配给其他指针时不需要您进行强制转换,反之亦然。但同样,如果您最终将 void 指针转换回正确的类型,您只会获得定义的行为。
回答by Gangadhar
For example you have a function
例如你有一个功能
void * abc(void *)
{
//...
}
int ExecBlock (void (*f) (void), int isSet)
{
return ExecBlock2( abc , NULL, isSet); //use name of the function which have void * as parameter type list and return type void *
}
int ExecBlock2(void *(*f)(void *), void *arg, int isSet)
{
... more code
}
见函数指针