gexogen
наглядна - да, но ничего не мешает объявить AutoCrit внутри блока, допустим, if()...
Pushkoff
>наглядна - да, но ничего не мешает объявить AutoCrit внутри блока, допустим, if()...
Ок, плюс - наглядна (больше чем AutoCrit похоже на естественный язык, а фигурные скобки делают вход и выход в крит секцию отчетливо видимыми), а какие минусы? Что заставит тебя продолжить делать
{
...
AutoCrit autoCrit(cs);
...
}
вместо
...
ScopedLock(cs)
{
...
}
?
gexogen
я почему-то не совсем уверен в
if (AutoCrit autocrit(g_cs))
Чисто теоретически почему может не работать?
Я потестировал (вместо Enter\Leave сделал printf и потестировал разные случаи) и вроде бы все ок.
Вот выражение:
if( AutoScopedLock _scoped_lock = _cs_ )
не помню точно, но вроде как по стандарту в таких случаях сразу вызовется AutoScopedLock(CRITICAL_SECTION*), после чего чтобы установить if выражение вызовется operator bool(). Таким образом это вход в крит секцию, а выход произойдет в деструкторе, который вызывается при выходе из блока if. (Так и происходило при тестировании).
Но если компилятор воспримет это как if( AutoScopedLock _scoped_lock = AutoScopedLock(_cs_) ), то нужно будет добавить еще bool m_acquired и ставить его в true внутри operator bool(), при входе в крит секцию, чтобы гарантировать выход 1 раз (деструктор в таком случае вызовется 2 раза).
В итоге учитывая оба варианта оставил у себя такой вариант ScopedLock:
class ScopedEnterCriticalSection { protected: CriticalSection* m_section; bool m_acquired; public: ScopedEnterCriticalSection(CriticalSection* cs) : m_section( cs), m_acquired( false) {} ~ScopedEnterCriticalSection( ) { if( m_acquired ) m_section->leave( ); } operator bool( ) { m_section->enter( ); m_acquired = true; return true; } }; #define ScopedLock( _cs_) if( ScopedEnterCriticalSection _scoped_lock = _cs_ )
(CriticalSection - обернутое CRITICAL_SECTION, чтобы было RAII)
void foo() { FILE* file = fopen( "test.txt", "rb"); if ( !file) { return; } atexit1( fclose( file), FILE*, file); ...много кода с кучей точек выхода... // файл закроется автоматически при выходе из функции }
Тема в архиве.