Article View: comp.std.c++
Article #3379Re: Q: Generic Callbacks -- "Object->*func(...)"
From: Ben Jones
Date: Wed, 21 Feb 1996 17:50
Date: Wed, 21 Feb 1996 17:50
119 lines
4213 bytes
4213 bytes
brian (b.c.) white (bcwhite@bnr.ca) wrote:
: Does the C++ standard allow for a generic callback to be specified?
: Basically, I'd like to be able to pass an arbitrary object and function of
: that object to be called at some later time. For example:
: void DoIt(ANYOBJECT* Object, void (ANYOBJECT::*CallBack)( ...parmlist... ))
: {
: [...]
: Object->*CallBack( ...parms... );
: [...]
: }
: I'd like to be able to call "DoIt" with any type of object and a pointer to
: any of that object's member functions that match the 'parmlist'. As it
: stands, any object passed in would have to be in the same class hierarchy
: as ANYOBJECT, thus basically requiring a unified class hierachy in order to
: do this genericly.
: [snip snip]
: So... Is this possible?
The following kluge works on all platforms that I have tried it on
including Sun, SGI, Alpha, Macintosh, PC:
#include <stdarg.h>
class Callback
{
public:
typedef void (Callback::*MF)();
typedef void (*F)();
Callback(F ff=0)
{
p = 0;
f = ff;
}
Callback(void *pp,...)
{
va_list ap; va_start(ap,pp);
p=(Callback*)pp;
mf = va_arg(ap,MF);
}
virtual void operator()()
{
if (p)
(p->*mf)();
else if (f)
f();
}
private:
Callback *p;
union { MF mf; F f; };
};
Essentially, the "Callback" class consists of an object pointer and a
function pointer. The constructors provide for two cases: a global
function (which causes a null object pointer to be stored) or a paired
object and member function pointer. The parenthesis operator is
overloaded so that a Callback object may be executed as though it were
a function pointer. It is declared virtual so that virtual callback
functions will work properly.
Now we can set up a callback very easily:
Callback mycallback;
...
mycallback = function;
...
mycallback = Callback(&object,&classname::memberfunction);
...
mycallback();
The above class can be defined with a template or macro such that
you can make variations on it for callback functions with various
argument types.
It is not typesafe. It is your responsibility to make sure that
"object" and "memberfunction" are compatible. However, as I said
before, it works everywhere that I've tried it.
------------
A simple extension to C++ would allow for a perfectly typesafe
callback scheme. All that is necessary is that the following
expressions:
object.function
pointer->function
be LEGAL without having to be followed by (). For them to be
legal there needs to be a container which can hold the values
of those expressions. I would suggest:
type (::*callback)(type1,type2,...)
That is, if you specify "::*" without a qualifying classname,
then "callback" can accept an expression like "object.function"
provided that "function" has a prototype of "type(type1,type2,..)".
Simple as that.
ANSI commitee please take note.
Ben Jones
Hughes Information Technology
bjones@eos.hitc.com
jones@cais.com
---
[ To submit articles: Try just posting with your newsreader. If that fails,
use mailto:std-c++@ncar.ucar.edu
FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Technical Details
Message-ID:
<4gfdck$i0g@zippy.cais.net>Path:
arc1-ca.pugleaf.net!chronicle.mti.sgi.com!austernReferences:
<4fti32$p3p@bcarh8ab.bnr.ca>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!chronicle.mti.sgi.com!austern From: jones@cais.cais.com (Ben Jones) Newsgroups: comp.std.c++ Subject: Re: Q: Generic Callbacks -- "Object->*func(...)" Date: 21 Feb 1996 09:50:36 PST Organization: Capital Area Internet Service info@cais.com 703-448-4470 Approved: austern@isolde.mti.sgi.com Message-ID: <4gfdck$i0g@zippy.cais.net> References: <4fti32$p3p@bcarh8ab.bnr.ca> NNTP-Posting-Host: isolde.mti.sgi.com X-Original-Date: 21 Feb 1996 15:23:00 GMT X-Newsreader: TIN [version 1.2 PL2] X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBVAwUBMStbmEy4NqrwXLNJAQETwQIAmk+iMfjzJ9J9eWwRTysUcfjhUKnQ0U9j JDMFC4YaVYqv0/LNp1jCF46owo3wSwrUySlSt2/eRy6hi5Rrrf56YQ== =AlDY Originator: austern@isolde.mti.sgi.com