如何在不同的类中使用函数指针

How to use a function pointer in different class?

本文关键字:函数 指针      更新时间:2023-10-16

在function.h文件中,我已经将一个函数声明为内联,例如

inline double foo(int &a)
{
     return a*double value
}

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

我想看看有什么不同。

试试这个:

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

首先,你不是用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("%fn", 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("%fn", 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。

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

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

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

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