V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
vcfghtyjc
V2EX  ›  C++

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

  •  
  •   vcfghtyjc · 2022-10-25 10:47:14 +08:00 · 1496 次点击
    这是一个创建于 770 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    函数指针代码示例

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

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

    函数指针仅仅是一个地址,不包含数据。std::function 还可以包含数据。
    例如 lambda 表达式可以捕获外层的变量,形成一个闭包。这时就不能用函数指针了。
    weeei
        6
    weeei  
       2022-11-17 21:23:06 +08:00
    @stein42 std::function 是正解,但因为有性能陷阱,又衍生出了各种优化写法。实际工程中不如函数指针方便调试。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1086 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 19:30 · PVG 03:30 · LAX 11:30 · JFK 14:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.