Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old February 10th, 2006, 06:25 PM
Damien
Guest
 
Posts: n/a
Default Which Callback implementation is better?

Hi all,

I'm messing around with various signal/slot mechanisms, trying to build
something lean and fast. I've used libsigc++, and Sarah Thompson's at
sigslot.sourceforge.net, and most of the others you can find by
Googling, but I wanted to try doing it myself and needed some advice on
different approaches.

Most signal/slot libraries are based on template classes containing a
pointer-to-object and pointer-to-memfunc. You can also do callbacks or
signals with a pointer or reference to the object only, and use
templating to create a signal or callback based on an object and a
templated member function call. The shortest code I can cobble
together that demonstrates both approaches is below, which I threw into
a main.cpp.

#include <iostream>

template <class Arg>
class Callback1ArgBase
{
public:
Callback1ArgBase(){}
virtual ~Callback1ArgBase(){}
virtual void operator()(Arg& arg){}
};

template <class T, class Arg, void (T::*F)(Arg)>
class Callback1ArgTemplate : public Callback1ArgBase<Arg>
{
public:
Callback1ArgTemplate(T& t):object(t){}
virtual ~Callback1ArgTemplate(){}
virtual void operator()(Arg& arg){(object.*F)(arg);}

private:
T& object;
};


template <class T, class Arg>
class Callback1ArgMemPtr : public Callback1ArgBase<Arg>
{
public:
Callback1ArgMemPtr(T* t, void (T::*f)(Arg)):object(t),func(f){}
virtual void operator()(Arg& arg){(object->*func)(arg);}

private:
T* object;
void (T::*func)(Arg);
};

class Client
{
public:
Client(){}
~Client(){}
void TellMeInt(int i)
{
std::cout << "\n Wotcha. Callback fired! Int is " << i <<
"\n";
}
};

template<class Arg>
class Server
{
public:
Server():callbk1argtemplate(0),callbk1argmemptr(0) {}
~Server()
{
if (callbk1argtemplate)delete callbk1argtemplate;
if (callbk1argmemptr)delete callbk1argmemptr;
}

//create a templated callback
template<class T, void (T::*F)(Arg)> void
BindCallback1ArgTemplate(T& t)
{
callbk1argtemplate = new Callback1ArgTemplate<T, Arg, F>(t);
}

//create a member function pointer callback
template<class T> void BindCallback1ArgMemPtr(T* t, void
(T::*F)(Arg))
{
callbk1argmemptr = new Callback1ArgMemPtr<T, Arg>(t, F);
}

void DoSomethingArg(Arg arg)
{
std::cout << "\n This is Server doing something with an arg on
the template version.\n";
(*callbk1argtemplate)(arg);
std::cout << "\n This is Server doing something with an arg on
the member pointer version.\n";
(*callbk1argmemptr)(arg);
}
private:
Callback1ArgBase<Arg>* callbk1argtemplate;
Callback1ArgBase<Arg>* callbk1argmemptr;

};

int main()
{
Server<int> server;
Client client;
server.BindCallback1ArgTemplate<Client, &Client::TellMeInt>(client);
server.BindCallback1ArgMemPtr(&client, &Client::TellMeInt);
int fred = -32767;
server.DoSomethingArg(fred);
return 0;
}

Both methods work, but the Callback1ArgTemplate version is smaller
because it doesn't contain a member function pointer (unless I
misunderstand how the compiler builds template classes). Without a
member function pointer you can't rebind to a different member
function. I'm an engineer, not a Computer Science grad, so could
anyone with a bit of CompSci experience comment on these approaches?
Also, I noticed that server.BindCallback1ArgMemPtr... call doesn't
require the addition of the <Client> template part, I assume that's
because it's implicit in the arguments to the function.

Thanks in advance,

Damien

  #2  
Old February 10th, 2006, 08:05 PM
AnonMail2005@gmail.com
Guest
 
Posts: n/a
Default Re: Which Callback implementation is better?

Damien wrote:[color=blue]
> Hi all,
>
> I'm messing around with various signal/slot mechanisms, trying to build
> something lean and fast. I've used libsigc++, and Sarah Thompson's at
> sigslot.sourceforge.net, and most of the others you can find by
> Googling, but I wanted to try doing it myself and needed some advice on
> different approaches.
>
> Most signal/slot libraries are based on template classes containing a
> pointer-to-object and pointer-to-memfunc. You can also do callbacks or
> signals with a pointer or reference to the object only, and use
> templating to create a signal or callback based on an object and a
> templated member function call. The shortest code I can cobble
> together that demonstrates both approaches is below, which I threw into
> a main.cpp.
>
> #include <iostream>
>
> template <class Arg>
> class Callback1ArgBase
> {
> public:
> Callback1ArgBase(){}
> virtual ~Callback1ArgBase(){}
> virtual void operator()(Arg& arg){}
> };
>
> template <class T, class Arg, void (T::*F)(Arg)>
> class Callback1ArgTemplate : public Callback1ArgBase<Arg>
> {
> public:
> Callback1ArgTemplate(T& t):object(t){}
> virtual ~Callback1ArgTemplate(){}
> virtual void operator()(Arg& arg){(object.*F)(arg);}
>
> private:
> T& object;
> };
>
>
> template <class T, class Arg>
> class Callback1ArgMemPtr : public Callback1ArgBase<Arg>
> {
> public:
> Callback1ArgMemPtr(T* t, void (T::*f)(Arg)):object(t),func(f){}
> virtual void operator()(Arg& arg){(object->*func)(arg);}
>
> private:
> T* object;
> void (T::*func)(Arg);
> };
>
> class Client
> {
> public:
> Client(){}
> ~Client(){}
> void TellMeInt(int i)
> {
> std::cout << "\n Wotcha. Callback fired! Int is " << i <<
> "\n";
> }
> };
>
> template<class Arg>
> class Server
> {
> public:
> Server():callbk1argtemplate(0),callbk1argmemptr(0) {}
> ~Server()
> {
> if (callbk1argtemplate)delete callbk1argtemplate;
> if (callbk1argmemptr)delete callbk1argmemptr;
> }
>
> //create a templated callback
> template<class T, void (T::*F)(Arg)> void
> BindCallback1ArgTemplate(T& t)
> {
> callbk1argtemplate = new Callback1ArgTemplate<T, Arg, F>(t);
> }
>
> //create a member function pointer callback
> template<class T> void BindCallback1ArgMemPtr(T* t, void
> (T::*F)(Arg))
> {
> callbk1argmemptr = new Callback1ArgMemPtr<T, Arg>(t, F);
> }
>
> void DoSomethingArg(Arg arg)
> {
> std::cout << "\n This is Server doing something with an arg on
> the template version.\n";
> (*callbk1argtemplate)(arg);
> std::cout << "\n This is Server doing something with an arg on
> the member pointer version.\n";
> (*callbk1argmemptr)(arg);
> }
> private:
> Callback1ArgBase<Arg>* callbk1argtemplate;
> Callback1ArgBase<Arg>* callbk1argmemptr;
>
> };
>
> int main()
> {
> Server<int> server;
> Client client;
> server.BindCallback1ArgTemplate<Client, &Client::TellMeInt>(client);
> server.BindCallback1ArgMemPtr(&client, &Client::TellMeInt);
> int fred = -32767;
> server.DoSomethingArg(fred);
> return 0;
> }
>
> Both methods work, but the Callback1ArgTemplate version is smaller
> because it doesn't contain a member function pointer (unless I
> misunderstand how the compiler builds template classes). Without a
> member function pointer you can't rebind to a different member
> function. I'm an engineer, not a Computer Science grad, so could
> anyone with a bit of CompSci experience comment on these approaches?
> Also, I noticed that server.BindCallback1ArgMemPtr... call doesn't
> require the addition of the <Client> template part, I assume that's
> because it's implicit in the arguments to the function.
>
> Thanks in advance,
>
> Damien[/color]
For callbacks, use the boost function and boost bind libraries. You
should at the very least evaluate them to see if the meet your needs.

  #3  
Old February 10th, 2006, 10:25 PM
Damien
Guest
 
Posts: n/a
Default Re: Which Callback implementation is better?

Tried Boost too. Pretty good, but I'm still wondering about what the
experts think of either approach above.

Damien

 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles