Обработка исключений в boost :: сигналы2 - PullRequest
0 голосов
/ 29 марта 2020

Я пишу библиотеку, в которой мне нужно выполнить некоторые специфические c задачи в деструкторе объекта (или, точнее, используемом мной средства удаления с shared_ptr). Мне нравится делать деструкторы / удалители не иначе как по соглашению. Я вызывал сигнал как побочный эффект одного из этих удалителей, который определенно является бросаемой операцией. Я понял, что, вероятно, должен найти способ вызвать сигнал до того, как объект будет удален, но это заставило меня задуматься: как лучше обрабатывать исключения, генерируемые из подключенных слотов? Я должен предположить, что любое количество вещей может быть связано, так что на самом деле нет никакого способа узнать, какое исключение может быть выдано, чтобы я мог добавить уловку для его обработки. Но даже если я вообще не буду вызывать какие-либо сигналы из noexcept кода, похоже, что это может быть проблемой, которая возникает позже. Единственное решение, которое я могу придумать, состоит в том, чтобы обернуть вызовы сигналов во всеобщую ловушку и зарегистрировать сообщение об ошибке, если выбрасывается слот, и предположить, что любая необходимая обработка c, определяемая исключением, будет происходить на стороне слота, но это кажется как запах кода для меня, и я бы предпочел не использовать ловушки вне самого кода регистрации.

Ради потомков, вот код, показывающий ситуацию, в которой я находился до того, как я удалил вызов сигнала. Удалитель довольно прост:

struct window_deleter
    {
        void operator()(window_base* window) const noexcept
            {
            window->destroy();
            delete window;
            }
    };

И вот функция, которую он вызывает:

void window_base::destroy() noexcept
    {
    if (!IsWindow(_hWnd))
        {
        log(logging::verbose_info)
            << L"Cannot destroy uninitialized window "
            << _wndProps.text << L".";
        return;
        }
    log(logging::verbose_info) << L"Destroying window \""
        << _wndProps.text << L"\"...";
    _wndProps.destroying = true;
    DestroyWindow(_hWnd);
    sig_destroyed_(this);    //not noexcept!
    }

Возможно, это присущий шаблон сигнала, который любой код (не исключая или нет) это вызывает сигнал, рискует быть вызванным исключением, которого он не ожидает. Если вы являетесь пользователем библиотеки boost :: signal2, нашли ли вы способы защиты от этого?

...