函数指针是不是只是 C 的遗产?感觉可以用抽象类来更好的实现相同功能

2022-10-25 10:47:14 +08:00
 vcfghtyjc

我理解的函数指针使用场景是在代码运行过程中,我们可以动态的选择和执行特定函数。函数指针需要定义函数的输入和输出类型,这和抽象类里面定义函数是一样的。

相对于抽象类,函数指针不需要很多代码去定义抽象类,只需要定义函数,可能更轻便。 但是我感觉函数指针的可读性和可维护性要更差一些,如果是大型项目也许抽象类是更好的实现方式?

不知道大家在实际中是怎么选择用抽象类还是函数指针。欢迎讨论!

函数指针代码示例

void my_int_func(int x)
{
    printf( "%d\n", x );
}
 
 
int main()
{
    void (*foo)(int);
    foo = &my_int_func;
    foo( 2 );
 
    return 0;
}

抽象类代码示例

class AbstractClass {

public:

virtual void my_int_func(int) = 0; 

class SomeClass:public AbstractClass {
public:

void my_int_func(int x){
 printf( "%d\n", x );
} 

}
 
 
int main()
{
    AbstractClass a = SomeClass()
    a.my_int_func(2);
 
    return 0;
}
1291 次点击
所在节点    C++
6 条回复
ysc3839
2022-10-25 11:02:50 +08:00
两者不等价,用函数指针的话就是一个函数指针。用抽象类且编译器使用虚函数表实现虚函数的话,那传进去的其实是虚函数表(里面是函数指针)+类指针。
vcfghtyjc
2022-10-25 11:09:12 +08:00
@ysc3839 看到有说法说函数指针的内存开销会稍微好一点点。确实不等价,但我觉得抽象类可以在功能上取代函数指针,这个理解对吗?
ysc3839
2022-10-25 11:27:23 +08:00
如果是 C++,用函数指针的话可以直接写 lambda 函数,也可以用类的静态函数实现。用抽象类的话则不能直接写 lambda 。个人觉得是否用抽象类还得看项目的整体设计。
ysc3839
2022-10-25 11:28:19 +08:00
@vcfghtyjc 功能上当然可以取代。
stein42
2022-10-25 14:15:16 +08:00
c++ 就用 std::function 。std::function 可以接受函数、方法、静态方法、lambda 表达式,只要参数和返回值类型匹配。
https://en.cppreference.com/w/cpp/utility/functional/function

抽象基类虽然功能上能实现,但是太啰嗦,对于每一种函数类型要定义一个基类,每一个函数要定义一个包装类。
而且运行时多一次查虚函数表的操作,同时也阻止了编译器优化。

函数指针仅仅是一个地址,不包含数据。std::function 还可以包含数据。
例如 lambda 表达式可以捕获外层的变量,形成一个闭包。这时就不能用函数指针了。
weeei
2022-11-17 21:23:06 +08:00
@stein42 std::function 是正解,但因为有性能陷阱,又衍生出了各种优化写法。实际工程中不如函数指针方便调试。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/889621

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX