By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,849 Members | 2,164 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,849 IT Pros & Developers. It's quick & easy.

callback design question

P: n/a
Hi, I'm implementing a class which will serve as a callback. It will
have multiple virtual operations, which will be called upon certain
events.
The user of the class can inherit from this class and implement the
virtual operations to fit his/her needs.
Each operation will have up to 3 parameters of either basic integral
types (e.g. int, unsigned, size_t) or pointers (e.g. const char*).
However these parameters can be stored in the class as attributes.
My question is - whould you rather design operations with parameters
or have these parameters as members of the class and the operations
would have no parameters?
Can this have a impact on the performance (copying the parameters via
stack)? I know, design first, then do the profiling and see.. ;) But
I'd like to hear your opinion.
Thanks

Feb 21 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
mliptak wrote:
Hi, I'm implementing a class which will serve as a callback. It will
have multiple virtual operations, which will be called upon certain
events.
The user of the class can inherit from this class and implement the
virtual operations to fit his/her needs.
Each operation will have up to 3 parameters of either basic integral
types (e.g. int, unsigned, size_t) or pointers (e.g. const char*).
However these parameters can be stored in the class as attributes.
My question is - whould you rather design operations with parameters
or have these parameters as members of the class and the operations
would have no parameters?
Can this have a impact on the performance (copying the parameters via
stack)? I know, design first, then do the profiling and see.. ;) But
I'd like to hear your opinion.
Thanks
I there is any possibility that the parameters would change during the
lifetime of the callback object then I would undoubtedly want the
parameters to be real parameters, rather than class attributes.

Class attributes would be an example of the 'accumulate and fire'
anti-pattern.

http://en.wikipedia.org/wiki/Accumulate_and_fire

john
Feb 21 '07 #2

P: n/a
I there is any possibility that the parameters would change during the
lifetime of the callback object then I would undoubtedly want the
parameters to be real parameters, rather than class attributes.
Yes, the parameters would change, however they are meaningful only
during the call of the operation.

Feb 21 '07 #3

P: n/a
On Feb 21, 10:00 am, "mliptak" <Meht...@gmail.comwrote:
Hi, I'm implementing a class which will serve as a callback. It will
have multiple virtual operations, which will be called upon certain
events.
The user of the class can inherit from this class and implement the
virtual operations to fit his/her needs.
Each operation will have up to 3 parameters of either basic integral
types (e.g. int, unsigned, size_t) or pointers (e.g. const char*).
However these parameters can be stored in the class as attributes.
My question is - whould you rather design operations with parameters
or have these parameters as members of the class and the operations
would have no parameters?
Can this have a impact on the performance (copying the parameters via
stack)? I know, design first, then do the profiling and see.. ;) But
I'd like to hear your opinion.
Thanks
Maybe before you are writing your own code, you want to think of the
best pattern that I know - using a well design lib that will do what
you need to do and that was writing by expert programmers, in this
case you may want to look at:
http://libsigc.sourceforge.net/doc.shtml
and
http://www.boost.org/doc/html/function.html
and
http://www.boost.org/doc/html/signals.html
as libraries writing by programmers who devoted enough time to the
problem and have enough skill to have a well design lib for other to
use. By saying this I don't mean that you don't have the skills, just
that it may save you time and if you don't find them useful then at
least you may find some good ideas
Have luck

Feb 21 '07 #4

P: n/a
mliptak wrote:
>>I there is any possibility that the parameters would change during the
lifetime of the callback object then I would undoubtedly want the
parameters to be real parameters, rather than class attributes.


Yes, the parameters would change, however they are meaningful only
during the call of the operation.
Which is why 'real parameters' are the natural fit. Class attributes
last for the lifetime of the object.

One situation in which class attributes would not only be ugly but
actually fail to work is when the same callback object was being used in
different threads of execution.

john
Feb 21 '07 #5

P: n/a
Maybe before you are writing your own code, you want to think of the
best pattern that I know - using a well design lib that will do what
you need to do and that was writing by expert programmers, in this
case you may want to look at:http://libsigc.sourceforge.net/doc.shtml
andhttp://www.boost.org/doc/html/function.html
andhttp://www.boost.org/doc/html/signals.html
as libraries writing by programmers who devoted enough time to the
problem and have enough skill to have a well design lib for other to
use. By saying this I don't mean that you don't have the skills, just
that it may save you time and if you don't find them useful then at
least you may find some good ideas
Have luck
Thanks for the info. Have you actually used any of these? I'm kind
of familiar with http://sigslot.sf.net - are the libs above better
than this one?

Feb 21 '07 #6

P: n/a
On 21 Feb, 08:58, "mliptak" <Meht...@gmail.comwrote:
Maybe before you are writing your own code, you want to think of the
best pattern that I know - using a well design lib that will do what
you need to do and that was writing by expert programmers, in this
case you may want to look at:http://libsigc.sourceforge.net/doc.shtml
andhttp://www.boost.org/doc/html/function.html
andhttp://www.boost.org/doc/html/signals.html
as libraries writing by programmers who devoted enough time to the
problem and have enough skill to have a well design lib for other to
use. By saying this I don't mean that you don't have the skills, just
that it may save you time and if you don't find them useful then at
least you may find some good ideas
Have luck

Thanks for the info. Have you actually used any of these? I'm kind
of familiar withhttp://sigslot.sf.net- are the libs above better
than this one?
libsigc and boost::signals are actually the same lib
(by the same people) with some cosmetic differences.
I am not familiar with sigslot but at short glance it
seems to offer similar, albeit more limited, functionality
to libsigc/signals, the only real difference I see is that
libsigc/signals thread safety is left entirely to the user.
The benefit of boost is that it is well documented,
tested, supported and portable. it is also an entry point
for future standard library extensions. (you also get
an added benefit of the rest of excellent boost libraries)

I have been using libsigc/signals for several years
and I warmly recommend it.
Feb 21 '07 #7

P: n/a
I have been using libsigc/signals for several years
and I warmly recommend it.
So I gave it a try and instead of using virtual functions I used the
signals..
But I gained nothing in terms of performance and also the interface
remained pretty much the same.
So what's the rationale behind using signals / slots?

Mar 1 '07 #8

P: n/a
On 1 Mar, 07:19, "mliptak" <Meht...@gmail.comwrote:
I have been using libsigc/signals for several years
and I warmly recommend it.

So I gave it a try and instead of using virtual functions I used the
signals..
But I gained nothing in terms of performance and also the interface
remained pretty much the same.
So what's the rationale behind using signals / slots?
signals/slots is a very simple library.

you have much less restrictive interface with signals than with
abstract bases.

struct my_interface
{
virtual void fun1(A &)=0;
virtual void fun2(B &)=0;
};

with this approach you have to implement both functions even if
you don't use one of them

signal<void (A&)asignal;
signal<void (B&)bsignal;

slots are arbitrary function objects
you can connect any function object that is convertible to
the slot

void fun(A&);
asignal.connect(&fun);
struct T
{
void fun(A&);
};
T t;
asignal.connect(bind(&T:fun, &t, _1));

you can bind extra arguments and adapt
interface to fit the signal.

void my_fun(A & a, int n);
asignal.connect(bind(&my_fun, _1, 4));

you have much more robust
and functional connection management.

void my_fun1(B &);
connection con = bsignal.connect(bind(&my_fun1, _1));
....
con.block();
...
con.unblock();
...
con.disconnect();

using signals::trackable and signals::scoped_connection you
can have automatic connection management

you can group/order slots. you can chain signals. you can
collate results.

now, of course you can implement all that functionality yourself.
the point is that you don't have to since someone else has done
it already.

Mar 1 '07 #9

P: n/a
On Mar 1, 12:17 pm, "dasjotre" <dasjo...@googlemail.comwrote:
On 1 Mar, 07:19, "mliptak" <Meht...@gmail.comwrote:
I have been using libsigc/signals for several years
and I warmly recommend it.
So I gave it a try and instead of using virtual functions I used the
signals..
But I gained nothing in terms of performance and also the interface
remained pretty much the same.
So what's the rationale behind using signals / slots?

signals/slots is a very simple library.

you have much less restrictive interface with signals than with
abstract bases.

struct my_interface
{
virtual void fun1(A &)=0;
virtual void fun2(B &)=0;

};

with this approach you have to implement both functions even if
you don't use one of them
You can do the default implementation in the base class as well,
instead of pure virtuals..
>
signal<void (A&)asignal;
signal<void (B&)bsignal;

slots are arbitrary function objects
you can connect any function object that is convertible to
the slot

void fun(A&);
asignal.connect(&fun);
struct T
{
void fun(A&);};

T t;
asignal.connect(bind(&T:fun, &t, _1));

you can bind extra arguments and adapt
interface to fit the signal.

void my_fun(A & a, int n);
asignal.connect(bind(&my_fun, _1, 4));

you have much more robust
and functional connection management.

void my_fun1(B &);
connection con = bsignal.connect(bind(&my_fun1, _1));
...
con.block();
..
con.unblock();
..
con.disconnect();

using signals::trackable and signals::scoped_connection you
can have automatic connection management

you can group/order slots. you can chain signals. you can
collate results.

now, of course you can implement all that functionality yourself.
the point is that you don't have to since someone else has done
it already.
Thanks for the explanation.
I think I just did not see the use for all this because I did not come
over a realworld application where this could be a perfect fit.

Mar 1 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.