Всем привет
бывает такой юзкейс что надо форсировать вызов клинера не дожидаясь
его стандартного вызова в деструкторе (в .NET есть похожий метод Close)
но в Loki есть почему то только Dismiss позволяющий забыть про клинер
типичный пример: открываем файл, добавляем в клинер, так, что если произойдет
преждевременный выход из функции то клинер должен закрыть файл,
но если мы дошли до "конца" функции то нам надо форсировать вызов клинера
дабы закрыть файл и после этого например удалить его
вот пример
int _tmain(int argc, _TCHAR* argv[])
{
auto fh = fopen("c:/tes22", "w+");
ScopeGuard g1 = MakeGuard(fclose, fh);
// если преждевременный выход из функции закрыть файл и выйти
// если дошли сюда, удалить файл
auto res = std::remove("c:/tes22");
return 0;
}
но файл не удаляется так как он открыт
а что если добавить virtual к деструктору базового класса
loki/ScopeGuard.h
virtual ~ScopeGuardImplBase()
{}
и добавить вызов Dismiss дабы не быть вызванными повторно во время стандартного вызова деструктора
template <typename J>
void SafeExecute(J& j) throw()
{
if (!j.dismissed_)
{
#ifndef LOKI_SCOPEGUARD_NO_EXCEPTIONS
try
{
j.Execute();
}
catch(...)
{}
#else
j.Execute();
#endif
Dismiss();
}
}
теперь мой пример кода можно переписать так
int _tmain(int argc, _TCHAR* argv[])
{
auto fh = fopen("c:/tes22", "w+");
ScopeGuard g1 = MakeGuard(fclose, fh);
// если преждевременный выход из функции закрыть файл и выйти
// если дошли сюда, удалить файл
g1.~ScopeGuardImplBase();
auto res = std::remove("c:/tes22");
return 0;
}
насколько корректна такая переделка? или можно как то поприличнее?