Я в настоящее время использую Visual Studio Express C++ 2008 и имею некоторые вопросы об упорядочивании блока выгоды. К сожалению, я не мог найти ответ в Интернете, таким образом, я ставлю эти вопросы экспертам.
Я замечаю, что, если выгода (...) не помещается в конце блока выгоды, компиляция приведет к сбою с ошибкой C2311. Например, следующее скомпилировало бы:
catch (MyException)
{
}
catch (...)
{
}
в то время как следующее не было бы:
catch (...)
{
}
catch (MyException)
{
}
a. Я мог спросить, определяется ли это в стандарте языка C++, или если это - просто компилятор Microsoft, являющийся строгим?
b. C# и Java имеют те же правила также?
c. Как в стороне, я также попытался делать базовый класс и производный класс, и поместить оператор выгоды для базового класса перед оператором выгоды для производного класса. Это скомпилировало без проблем. Там никакие стандарты языка не принимают меры против такой практики?
По стандарту порядок имеет значение. По сути, будет пойман первый улов, соответствующий исключению.
a) Поскольку catch (...)
сделает любые последующие уловы неактуальными, стандарт разрешает только последний улов.
б) C # и Java имеют похожие правила.
c) перехват (по ссылке или указателю) базы до того, как производный класс сделает код производного неактуальным. Однако стандарт разрешает это
Так называемый обработчик по умолчанию catch(...)
должен быть последним в списке обработчиков. Это действительно требуется стандартом. Однако это требование относится только к обработчику по умолчанию.
В остальном стандарт не ограничивает упорядочивание обработчиков, что означает, что в общем случае вы можете создать обработчик, который будет "перехватывать" все исключения, которые в противном случае попали бы к другому обработчику ниже по списку (таким образом делая последний обработчик бесполезным).
Более того, совершенно законно повторять одно и то же catch
предложение (с одним и тем же типом) несколько раз
catch (int) {
// ...
}
catch (int) {
// ...
}
даже несмотря на то, что только первый из них будет иметь шанс поймать хоть что-нибудь. Хороший компилятор выдаст предупреждение для подобных случаев, но формально это не является ошибкой.
Из стандарта C++ 15.3/5 "Обработка исключения":
Обработчики для пробного блока искомы в порядке появления. Это позволяет писать обработчики, которые никогда не могут быть выполнены, например, помещая обработчик для производного класса после обработчика для соответствующего базового класса.
A
...
в функции объявления исключений обработчика аналогичны функциям...
в объявлении параметров функции; он задает соответствие для любого исключения. Если присутствует, то...
Обработчик является последним обработчиком для своего пробного блока.