локи клинер, странный юзкейс
От: jyuyjiyuijyu  
Дата: 26.02.15 05:22
Оценка:
Всем привет

бывает такой юзкейс что надо форсировать вызов клинера не дожидаясь
его стандартного вызова в деструкторе (в .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;
}



насколько корректна такая переделка? или можно как то поприличнее?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.