C ++ форс-сигналы 2 - PullRequest
       32

C ++ форс-сигналы 2

2 голосов
/ 19 сентября 2011

В c # у нас есть ключевое слово события, представляющее собой особый тип делегата, который может быть вызван только из класса, который его объявил.Итак, есть ли способ сделать это в нативном c ++ с использованием boost :: signal2, если так, дорого ли это с точки зрения производительности?

1 Ответ

3 голосов
/ 19 сентября 2011

В целом, подходы к ограничению возможности вызова функцией C ++ основаны на передаче фиктивного параметра типа, экземпляр которого либо нельзя создать вне этого класса (частная фабрика или конструктор с объявлением «друг» для намеченного класса).

Применение этого к значению boost :: signal2 :: signal приведет к определению сигнала, который имеет посторонний параметр.

Если вам действительно нужно сделать его не вызываемым, помните, что это просто элемент объекта (по крайней мере, так как я его использую ...) - вы можете объявить его как закрытый или защищенный член и предоставить публичную функцию для подключения к нему.

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;
}

Конечно, вы можете перестроить метод ConnectToFoo, чтобы взять FooHandler и выполнить связывание там, если ваша модель достаточно жесткая.

Что касается аспекта производительности, то при использовании хорошего компилятора тип-пустышка фактически свободен, и этот механизм представляет собой дополнительный вызов функции или два раза для обработчика (не для сигнала).

...