Когда у меня есть метод, который вызывает набор методов, которые обеспечивают надежную гарантию, у меня часто возникает проблема с откатом изменений, чтобы также иметь сильный метод гарантии. Давайте используем пример:Сильный метод гарантии, вызывающий сильные методы гарантии
// Would like this to offer strong guarantee
void MacroMethod() throw(...)
{
int i = 0;
try
{
for(i = 0; i < 100; ++i)
SetMethod(i); // this might throw
}
catch(const std::exception& _e)
{
// Undo changes that were done
for(int j = i; j >= 0; --j)
UnsetMethod(j); // this might throw
throw;
}
}
// Offers strong guarantee
void SetMethod(int i) throw(...)
{
// Does a change on member i
}
// Offers strong guarantee
void UnsetMethod() throw(...)
{
// Undoes a change on member i
}
Очевидно, что UnsetMethod может выбрасывать. В этом случае мой MacroMathod() предлагает только базовую гарантию. Тем не менее, я сделал все, что мог, чтобы предложить надежную гарантию, но я не могу быть абсолютно уверен, что мой UnsetMethod() не будет бросать. Вот мои вопросы:
- Должен ли я попытаться предложить сильную гарантию в этом случае?
- Должен ли я документировать свой MacroMethod() как имеющий базовую или сильную гарантию? Даже если это очень маловероятно, UnsetMethod будет бросать?
- Можете ли вы увидеть способ сделать этот метод действительно надежной гарантией?
- Возможно, мне следовало бы поставить вызов UnsetMethod() в попытке, но это кажется довольно тяжелым, и что мне делать в catch?
Спасибо!
Я видел только сильные гарантии были применены к не методам стоящих функций. Я полагаю, это можно сделать, но нам действительно нужно понять контекст больше. Меняя член i на то, что именно есть какая-то глобальная переменная, мы меняем состояние? Если это объект. Затем вы делаете копию. Предварительно создавайте операции, если все они работают, тогда вы заменяете реальную. –
Как примечание стиля (с некоторыми довольно неприятными последствиями), вы должны пересмотреть использование спецификаций исключений. Известно, что они вызывают серьезные проблемы, пытаясь полностью удалить их с языка. –
@Stanley: Было обсуждение с другом относительно этого. Проделали также некоторые тесты с компилятором и прочитали рациональное повышение. Ты прав. Я, хотя эта критика/ограничение заключалась в том, чтобы указывать типы в спецификации, а не в спецификации вообще. Это объясняет, почему я удерживал его, чтобы бросить() против броска (...). Спасибо за комментарий и обновим мой код. – Geeho