Search code examples
c++eventsboost-signals2

c++ boost signals 2


In c# we have the event keyword which is an special kind of delegate which can only be invoked from withing the class that declared it. So, is there a way of doing this in native c++ using boost::signals2, if so, is it expensive from a performance stand point?


Solution

  • In general, approaches to restricting the callability a C++ function rely on passing dummy parameter of a type that either can't be instantiated outside that class (private factory or constructor with a 'friend' declaration for the intended class).

    Applying this to a boost::signals2::signal would result in a signal definition that had the extraneous parameter, though.

    If you really need to make it un-callable, remember that it is just an object member (at least, as I use it...) - you can declare it as a private or protected member and provide a public function for connecting to it.

    class FooEmitter
    {
    public:
        boost::signals2::scoped_connection ConnectToFoo(boost::function<void (Emitter&)>& handler)
        {
            return fooSignal.connect(handler);
        }
    
        void triggerFoo() {
            fooSignal(*this);
        }
    private:
        boost::signals2::signal<void (Emitter&)> fooSignal;
    };
    
    class FooHandler
    {
    public:
        FooHandler()
        {
            fooConnection = getAnEmitter().ConnectToFoo(boost::bind(&FooHandler::HandleFoo, this, _1);
        }
    
        void HandleFoo(Emitter&)
        {
            // handler body
        }
    
    private:
        boost::signals2::scoped_connection fooConnection;
    }
    

    You could of course re-arrange the ConnectToFoo method to take a FooHandler& and do the binding in there, if your model is rigid enough.

    As for the performance aspect, the dummy type is effectively free with a good compiler, and this mechanism is an additional function call or two once per handler (not per signal).