在function.h文件中,我已将函数声明为内联函数,例如
inline double foo(int &a)
{
return a*double value
}
在a.cpp文件中,我已经包含了function.h文件并在很多地方调用了foo函数。 a.cpp文件也有一个b类实例,我想在b实例中调用foo函数。当我在b中调用一个函数时,我想将函数指针传递给b,这样我就可以在b中调用foo函数而不包含function.h文件。
b.cpp file
void b_foo(a function pointer to foo function)
{
call foo
}
由于我已将该函数声明为内联,因此我不确定传递函数指针是否有效而不是仅仅包含b.cpp中的function.h文件。
我想看看会有什么不同。
答案 0 :(得分:1)
试试这个:
typedef double (*foo_ptr)(int &);
void b_foo(foo_ptr f)
{
if (f != NULL) {
double d = f(5);
}
}
void f() {
b_foo(foo);
}
typedef
可以更容易地引用指向函数的指针类型。
调用时不需要取消引用指针(可以,但没有必要)。作为参数传递时,您也不需要获取函数的地址(再次,您可以,如果需要)
请注意
inline double foo(int &a)
{
return a*double value
}
无效,因为它有语法错误。试试:
inline double foo(int &a)
{
return a*4.5;
}
你也可以声明/使用double
局部变量而不是双字面
注意:您正在讨论实例中的函数。如果您确实想要调用成员函数,则需要:
typedef double (*B::foo_ptr)(int &);
其中B
是声明函数的类。然后以这种方式使用它:
B b;
foo_ptr f = B::foo;
b.*f(5);
答案 1 :(得分:1)
首先,你不是用C编程的。你是用C ++编程的。这是一种不同的语言。 C没有引用或类。在你的代码中,你没有使用类,但你正在使用引用(无缘无故)。
其次,考虑“函数指针”的含义。它是该函数的代码的地址。现在考虑“内联”的含义。这意味着该功能在机器代码中不是独立存在的。它的源(概念上)放在它被调用的地方,并且编译调用函数。所以你想要获取不存在的东西的地址。
简短的回答是你不能。
你想要达到什么目的?你想永远从b打电话给foo吗?如果是这样,您不需要间接。您可以调用内联函数并将其内联到调用站点,或者您可以调用非内联函数并生成实际函数调用。
// a.c
double foo(int a) { return a * 3.1415926; }
// b.c
double foo(int a); // declaration, not definition.
void b(void) { printf("%f\n", foo(10)); }
int main() { b(); return 0; }
构建:
gcc -O2 -c -o a.o a.c
请注意,在编译b.c时,编译器不知道foo的功能,它只知道它的签名。
gcc -O2 -c -o b.o b.c
这将两个部分链接到一个程序中,并在开头和结尾添加部件,以便运行它:
gcc -o program a.o b.o
不同之处在于效率。内联允许许多优化(直到使用参数的值来预先计算结果并完全消除代码,就像这里一样)。内联这种优化的地方仍然可以更快,因为它消除了函数调用开销,并且可以允许更好的寄存器分配,以及使代码更有可能在缓存中。但是内联可能很糟糕,因为它会导致代码膨胀和缓存污染,使得代码不太可能在缓存中。
如果您在编译时不知道要从b调用哪个函数,则需要间接。因此,您将拥有foo_1和foo_2,并且您将传递给指向其中一个的指针,并且它将调用该指针指向的函数,而不知道它是哪一个。这有性能损失,但有时是必要的。
double foo_1(int a) { return a * 3.1415926; }
double foo_2(int a) { return a * 2.81; }
void b(double (*foo)(int)) { printf("%f\n", foo(10)); }
int main(int argc, char *argv[])
{
if (argc < 2) return;
b(argv[1][0]-48 ? &foo_1 : &foo_2);
return 0;
}
C ++有一个功能,您可以告诉编译器从相同的源代码生成两个版本的函数b:一个始终调用foo_1,另一个始终调用foo_2。然后可以在两个调用站点内联foo_1和foo_2,而不是选择将指针传递给foo_1或foo_2到b,您需要选择调用b_with_foo_1或b_with_foo_2。
答案 2 :(得分:0)
点击here“功能指针”这可能对您有所帮助。我不知道,但我是c的新人。我相信你需要它。
答案 3 :(得分:0)
它是否能产生真正的性能差异,您只能通过实现两个版本,启用编译器优化和比较速度来找到它们。这取决于与其他代码相关的太多因素是可预测的。这显然取决于你的函数被实际调用的次数。
但总的来说,内联可能会对速度产生重大积极影响。
保持灵活性,并且假设您显然使用的是C ++(而不是C),那么使用更多 C ++ - 类似的方法是个好主意处理这种情况。有关各种可能性及其含义,请参阅this SO post。如果您遵循问题中列出的策略之一,编译器可能会尽可能地内联,同时您仍然可以获得函数指针的灵活性。