C++函数指针与子类

C++ Function pointers vs Subclasses

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

我可以在函数指针和子类对象之间进行选择。为了明确起见,比如说我必须通知某个对象某个动作(例如计时器(;参考以下两个选项(用于演示目的的非常基本的代码(:

版本1

typedef void TimerCallback(void *args);
class Timer{
public:
  Timer();
  ~Timer();
  void schedule(TimerCallback *callback, void *args, long timeout)=0;
  void cancel();
};

版本2

class TimerTask{
  public:
    TimerTask();
    virtual ~TimerTask();
    void timedout()=0;
};
class Timer{
  public:
    Timer();
    virtual ~Timer();
    void schedule(TimerTask *callback, long timeout)=0;
    void cancel();
};

哪一种是标准C++方式,哪一种有效?如果你在这方面还有其他建议,请告诉我。

如果我在这方面不清楚,请告诉我。

感谢

我会说std::functionstd::bind。然后,不管您是想使用继承类、独立函数、成员函数还是lambda。


顺便说一句,如果有人好奇的话,我前段时间做了一个简单的计时器事件处理,作为对另一个问题的回答。它展示了例如std::functionstd::bind的使用:https://stackoverflow.com/a/11866539/440558.

我认为最好使用boost(or std since C++11)::function来保存回调,使用boost::bind来绑定它的参数,或者使用boost::signal。这将是一个更通用和详细的解决方案,代价是非常小的惩罚。

http://www.boost.org/doc/libs/1_53_0/doc/html/signals2.html

您使用的是面向对象编程,应该遵循面向对象编程范式。

在我看来,使用对象,而不是函数指针,是更干净、更好的方法

您还可以尝试使用访问者模式来使代码变得更好、更灵活。

您还可以考虑发布者/订阅者模式。

函数指针有效地阻止了您使用闭包-将方法分配给您的事件处理程序(这并不完全是,但它会以这种方式限制您,因此该解决方案用处不大(。

我会投票支持面向对象的方法。如果你使用C++11,你可能会大大简化你的代码:

#include <cstdio>
#include <functional>
class Emitter
{
private:
    std::function<void(int)> eventHandler;
public:
    void SetEventHandler(std::function<void(int)> newEventHandler)
    {
        eventHandler = newEventHandler;
    }
    void EmitEvent()
    {
        eventHandler(42); // + error-checking
    }
};
class Handler
{
private:
    void HandleEvent(int i)
    {
        printf("Event handled with i == %dn", i);
    }
public:
    void AttachEmitter(Emitter & e)
    {
        e.SetEventHandler([this](int i) { HandleEvent(i); });
    }
};
int main(int argc, char * argv[])
{
    Emitter e;
    Handler h;
    h.AttachEmitter(e);
    e.EmitEvent();
}

两者都有效。你的第一个是"C风格",需要一个静态函数。第二个版本是"C++风格",允许您使用TimerTask的实例。

通常,应该使用版本2,因为它消除了对静态函数的需要。