views:

358

answers:

3

I make my boost::signals public because I'm lazy.

class Button {
public:
    signal<void()> clicked;
};

int main() {
    Button btn;
    btn.clicked.connect(handleClick);
}

... rather than encapsulating with a Button::OnClicked(boost::function<void()>).

Is this going to come back and bite me?

+1  A: 

It depends.

It has bitten me before when I wanted to add some special logic each time an object connected to another object's signals. This is the most likely case to bite you.

Also, it can make it difficult to keep track of exactly when other objects are connecting to any given object.

I would say hide the connections behind a function to be on the safe side.

I usually use a macro to do the vanilla function definition.

#define SIGNAL(slot,name) connection name(function<slot> func) { return _##name##.connect(func);}

And then in a class definition:

SIGNAL(void(),clicked)

This assumes you follow the convention of naming the signal '_clicked' but you can substitute any convention. It generally keeps the interface cleaner for all of your classes. When you want to add special connection logic you can, without changing all of the other objects that use the signal.

EDIT

One instance was when the signal object was actually moved to a delegate implementation inside another class, but it still made sense for objects to connect through the original class. This broke all of the places that tried to connect to it. If they had been using function accessors to connect, it would have been as simple as changing the function to look up the signal in the delegate. But as it was it broke all the users of the original class.

Or, when I wanted to log each time something connected to a specific signal. This was just for debugging purposes, but it can be very helpful if you suspect something wonky is going on like cycles in your signal connections.

thanks; can you tell me about a specific case where you needed this?
A: 

Well, this questions really has nothing to do with boost::signal or function - it's all about encapsulation.

Do client's of the Button class need complete access to clicked? If all they ought to be able to do is subscribe to it then allow only that with the OnClicked method. Exposing more than that is likely to bite you IMHO.

As always you balance costs vs benefits. In this case the cost is very low. If you were on my team I'd strongly recommend you add the OnClicked method.

MattyT
A: 

I set them public as well and use upper-camel-case for its object name. This approach never backfired on me.

StackedCrooked