user630286
user630286

Reputation: 65

C++ Function pointers vs Subclasses

I am in a position to choose between function pointers and subclassed objects. To make it clear, say I have to notify some object of some action (a timer for example); refer to the following two choices (a very basic code for demo purposes):

Version 1

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

Version 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();
};

which one is the standard C++ way and which one is efficient? Please let me know if you have any other suggestions in this regard.

Please let me know if I am not clear in this regard.

Thanks

Upvotes: 4

Views: 669

Answers (5)

Some programmer dude
Some programmer dude

Reputation: 409166

I would say std::function and std::bind. Then it doesn't matter if you want to use inherited classes, standalone functions, member functions or lambdas.


By the way, if anyone is curious I made a simple timer event handling some time ago, as an answer to another question. It's showcasing the use of e.g. std::function and std::bind: https://stackoverflow.com/a/11866539/440558.

Upvotes: 14

Spook
Spook

Reputation: 25927

Function pointer effectively prevents you to use closures - assigning methods to you event handler (This is not entirely true, but it will restrict you in such way, that this solution is not much of a use).

I would vote on object-oriented approach. If you use C++11, you may simplify your code a lot:

#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 == %d\n", 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();
}

Upvotes: 1

john.pavan
john.pavan

Reputation: 950

Both work. Your first one is "C style" and will require a static function somewhere. The second version is "C++ style" and allows you to use an instance of TimerTask.

Generally, version 2 should be used because it removes the need for a static function.

Upvotes: 0

kassak
kassak

Reputation: 4184

I think it's better to use boost(or std since C++11)::function to hold callback and boost::bind to bind it's arguments, or to use boost::signal. That would be more general and verbose solution at cost of really small penalty.

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

Upvotes: 4

Dariusz
Dariusz

Reputation: 22241

You are using object-oriented programming and you should follow the object-oriented programming paradigms.

In my opinion using objects, not function pointers, is the cleaner and generally better way to do.

You can also attempt to use a visitor pattern to make the code even better and more flexible.

You can also consider publisher/subscriber pattern.

Upvotes: 2

Related Questions