1

在 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 文件。

我想看看可能有什么不同。

4

4 回答 4

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 &);

whereB是声明函数的类。然后以这种方式使用它:

B b;
foo_ptr f = B::foo;
b.*f(5);
于 2012-04-16T02:21:49.027 回答
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

请注意,在编译 bc 时,编译器不知道函数 foo 做了什么,它只知道它的签名。 gcc -O2 -c -o b.o b.c

这将这两个部分链接到一个程序中,并在开头和结尾添加部分,使其可以运行它: gcc -o program a.o b.o

区别在于效率。内联允许许多优化(直到使用参数的值来预先计算结果并完全消除代码,就像这里一样)。在无法进行此类优化的地方内联仍然可以更快,因为它消除了函数调用开销,并且可以允许更好的寄存器分配,以及使代码更有可能在缓存中。但是内联可能很糟糕,因为它会导致代码膨胀和缓存污染,从而使代码不太可能在缓存中。

如果在编译时不知道要从 b 调用哪个函数,则需要间接调用。因此,您将拥有 foo_1 和 foo_2 并且您将传递给 b 指向其中任何一个的指针,并且它将调用该指针指向的函数,而不知道它是哪一个。这会降低性能,但有时是必要的。

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。

于 2012-04-16T02:50:28.067 回答
0

单击此处“指向函数的指针”这可能对您有所帮助。我不知道,但我是c新手。我相信你需要它。

于 2012-04-16T02:22:44.957 回答
0

它是否会产生真正的性能差异,您只能通过实现两个版本、打开编译器优化并比较速度来确定。它取决于与代码的其余部分相关的太多因素,无法预测。这显然特别取决于您的函数实际调用了多少次。

但一般来说,内联可能会对速度产生重大的积极影响。

为了保持灵活性,并且考虑到您显然使用的是 C++(而不是 C),最好使用更多类似 C++ 的方法来处理这种情况。有关各种可能性及其含义,请参阅此 SO 帖子。如果您遵循该问题中概述的策略之一,编译器可能会尽可能内联,同时您仍然可以获得函数指针的灵活性。

于 2012-04-16T02:38:02.660 回答