[comp.lang.c++] Callback routines - a question

huw@xstuart.siesoft.co.uk (Huw Roberts) (12/16/89)

I am trying to implement a generalised callback mechanism within C++.
Unfortunately I can't see a simple solution to this.

I'm sure someone must have done this before but I can't find any
references so I have decided to publish my problem on the net...

Essentially I want to be able to compile something better than the
following program (which works, by the way).

    #include <CC/stdio.h>

    class ServiceUser
    {
	int x;
    public:
	void func(int a);
    };


    class ServiceProvider
    {
	ServiceUser *a;  /* Service Provider needs to know class of User */
	void (ServiceUser::*x)(int);
    public:
	ServiceProvider(ServiceUser *u, void (ServiceUser::*f)(int))
	{
	    a=u;
	    x=f;
	};
	void doit()
	{
	    (a->*x)(3);
	}
    };

    void ServiceUser::func(int a)
    {
	x = a;
	printf("Hello\n");
    }

    main()
    {
	ServiceUser u;
	ServiceProvider p(&u, ServiceUser::func);/* I have to provide both */
						 /* Ideally: p(u.func); */
	p.doit();
    }

To summarise the problems I have with this approach:
(i)  When I pass the callback to the service provider I have to provide
    both the object requiring the service and the member of the object
    which is to be notified.  This problem is not really important, but
    it would be nice to be able to go "p(u.func)"
(ii)  The service provider needs to know the class of the service user.
    This is much more important.

Perhaps I can get round problem (ii) by using a "callback class" which the
service provider knows about from which all service users are derived. 
This seems unnecessarily complicated and has the further flaw that if you
want an object to be called back from many different places you have to
multiply inherit the callback class (I don't even know if it is possible
to inherit multiple virtual functions from different instances of a base
class).

Any ideas?

Huw.

(P.S.  I believe the normal form is for you to send replies directly to me
then I post a summary on the newsgroup (cuts down on news traffic that way))