Вызывается C — безопасный для исключений способ обеспечения глобальной функции очистки

#c

#c

Вопрос:

Контекст:

Предположим, что внешней библиотеке требуется, чтобы была вызвана ее globalCleanup() функция, чтобы гарантировать, что все ее ресурсы очищены (она может выделить некоторые глобальные ресурсы во время любого из своих вызовов.) Клиентская функция client() делает это перед каждой из своих многочисленных return функций, но, конечно, это не безопасно для исключений, и код повторяется.

Проблема:

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

TLDR: Как вызвать глобальную функцию очистки в стиле RAII?

Комментарии:

1. Прочитайте о ScopeGuard .

Ответ №1:

 class Cleaner {
  public:
    Cleaner() {}
    ~Cleaner() { ExtLib::CleanGlobal(); }
};

void client() {
  Cleaner cleaner;

  // Code that works with ExtLib
}
  

Комментарии:

1. Да, моя первая мысль. Он также мог бы использовать void (*f)(void) в конструкторе и вызывать его в деструкторе, чтобы быть немного более повторно используемым. Я соглашусь, если не появится ничего лучшего. Кстати, в Boost должен быть такой класс 🙂

2. @Rafal Dowgird: Фактически существует boost::scope_exit класс.

Ответ №2:

 #include "loki/ScopeGuard.h"
client()
{
    LOKI_ON_BLOCK_EXIT(globalCleanup);
    // some codes here
}   // globalCleanup will be called when exit this block
  

Ответ №3:

Обертывание его классом, который очищается в деструкторе, кажется мне лучшим выбором. (Предполагая, что библиотека еще не реализована в виде классов.)