c++ callbacks to member functions of any generic object

Hi,

I would like to implments a c++ callback like this:

//pseudocode

//instantiate various user-defined objects:

Person me;
Person jack;
Person dianne;
Dog pooch;

// subscribe the objects to me's Notify() function, so that when me.Notify() is called, each subscribing objcect has its own OnNotify() called;

me.subscribe( jack.OnNotify() )
me.subscribe( dianne.OnNotify() )
me.subscribe( pooch.OnNotify() )

Person::OnNotify() will be defined differently than Dog::OnNotify(), but will have the same signature.

It is critical that I subscribe member functions to the callback rather than static functions.

Person::subscribe( function_pointer ) will insert the function pointer into a vector of function pointers.

Person::Notify() will iterate over the vector of function pointers, calling (*iter)() for each one.



I understand that this is rather difficult to do in c++ and that there are issues regarding type-safety, doing it with different types (Dog and Person), and needing to use member functions.

I have found examples online (and even on EE) that deal with these issues and use templates, passing of a pointer to the instance, templates, functors, etc. But the examples were not explained clearly or slightly different than what I need to do above.

I'm a little overwhelmed and was hoping one of y'all had crossed this bridge before and found a simple, correct solution.

Thanks a ton guys,

Perk
highqllcAsked:
Who is Participating?
 
jkrCommented:
Why son't you do that like

struct INotifySink {

virtual void OnNotify() = 0;
};

class Person : public INotifySink, public SomeOtherStuff {

public:

  void OnNotify() {

      // provide implementation
  }

};

class Dog : public INotifySink, public SomeDifferentOtherStuff {

public:

  void OnNotify() {

      // provide implementation
  }

};

Person me;
Person jack;
Person dianne;
Dog pooch;


class Notifier {

public:

  void subscribe(INotifySink* p) {

    m_vSubscribers.push_back(p);
  }

protected:

  vector<INotifySink*> m_vSubscribers;

  void NotifyAll () {

    for (vector<INotifySink*>::iterator i = m_vSubscribers.begin(); i != m_vSubscribers.end(); ++i) {

      i->OnNotify();
    }
  }
};


Notifier me;

me.subscribe( &jack);
me.subscribe( &dianne);
me.subscribe( &pooch);
0
 
OnegaZhangCommented:
Have you read this:
http://www.codeproject.com/cpp/FastDelegate.asp
Member Function Pointers and the Fastest Possible C++ Delegates
By Don Clugston.

It can store your member function pointer into a container.
0
 
ravenplCommented:
Or use portable boost::function
http://www.boost.org/libs/bind/bind.html
0
 
highqllcAuthor Commented:
thanks for the ideas...  I like jkr's suggestion. It is very easy to understand and works well in my implmentation.
0
 
highqllcAuthor Commented:
jkr,

How should I handle the destruction of subscribing objects?  I don't want NotifyAll() to attempt to dereference a pointer to an object that no longer exists.  
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.