Re[12]: delete в Деструкторе
От: Юрий Жмеренецкий ICQ 380412032
Дата: 20.08.09 19:08
Оценка:
Здравствуйте, Николай Ивченков, Вы писали:

НИ>... Забыть вызвать close всё-таки можно, и во время штатной работы программы это никак не проявится. Поэтому, вероятно, выбранную стратегию следует указывать при создании объекта, а в деструкторе проверять, был ли вызван close. Если вызова close не было, но явно такое намерение не было зафиксировано, то деструктор должен выкинуть assertion failed или сообщить о внутренней ошибке в программе каким-то иным способом. Т.е. надо что-то вроде:


НИ>
enum ClosingPolicy { close_explicitly, close_soever };

НИ>....

НИ>X::X(ClosingPolicy closing_policy = close_explicitly) :
НИ>  m_closing_policy(closing_policy) {}

НИ>void X::close()
НИ>{
НИ>  if (closed)
НИ>    return;
НИ>  if (!api::close(....))
НИ>    throw some_exception();
НИ>  assert(closed);
НИ>}

НИ>X::~X()
НИ>{
НИ>  if (!closed)
НИ>  {
НИ>    assert(m_closing_policy != close_explicitly)
НИ>    api::close(....);
НИ>  }
НИ>}

Хороший вариант. Не соглашусь только с заменой assert'a в X::close на 'if (closed)return'. Повторный вызов — такая же логическая ошибка как и отсутствие вызова. Это не оговоривалось, но assert там присутствовал именно из этих соображений.

При некоторых условиях можно пойти дальше — если api::close возвращает несколько категорий ошибок ('close' как аналогия здесь уже мало подходит, хотя...), то в конструкторе можно указать, какие коды возврата необходимо транслировать в исключения. Если указана генерация хотя бы одного исключения (если дать возможность указывать несколько типов), то проверка в деструкторе на явный вызов close должна выполняться, иначе (игнорирование всех ошибок) ошибочным должен считаться явный вызов close, т.к. в этом случае вызов не приведет к исключению, тогда как основной его смысл — именно детектирование исключений.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.