Как поймать исключение в списке инициализации?

У меня вопрос, как отловить исключение в списке инициализации.

Например, у нас есть класс Foo, производный от Bar

class Foo {

public:
Foo(int i) {throw 0; }

}

class Bar : public Foo{

public:

Bar() : Foo(1) {}

}

person skydoor    schedule 14.03.2010    source источник


Ответы (4)


Я думаю, что синтаксис похож на this (хотя лучше улавливать такие вещи в вызывающем. И что ты собираешься делать, когда поймаешь это?)

Bar::Bar()
try
  : Foo(1)
{
}
catch( const SomeException &e )
{
}
person Community    schedule 14.03.2010
comment
Ого, это какой-то странно выглядящий код. - person Michael Myers; 14.03.2010
comment
Обратите внимание, что это нельзя использовать для игнорирования исключения. Если блок catch не генерирует исключение сам по себе, исходное исключение автоматически генерируется повторно (подробности см. В связанном GOTW). - person sth; 14.03.2010
comment
@sth: конечно может, только return. - person Potatoswatter; 14.03.2010
comment
@Potatoswatter, нет, не может. Насколько я знаю, вы не можете даже return; в теле такого catch блока для ctor-инициализатора (в отличие от блока catch других блоков try-функций). - person Johannes Schaub - litb; 14.03.2010
comment
@ Йоханнес: эй, ты прав, §15.3 / 15. Кроме того, вы не можете пытаться выполнить инициализацию: обращение к любому нестатическому члену или базовому классу объекта в обработчике для блока-попытки конструктора или деструктора для этого объекта приводит к неопределенному поведению. Это отстой! - person Potatoswatter; 14.03.2010
comment
@Potatoswatter: Это не отстой, просто нет объекта, на который вы могли бы сослаться в этот момент. - person Georg Fritzsche; 14.03.2010
comment
@gf: звучит немного круто. Вы можете не выдавать гарантии на все, кроме последнего инициализированного базового / нестатического члена, и быть уверенными, что они действительны. Допустим, что более удобная языковая спецификация не была бы очень простой или особенно полезной. - person Potatoswatter; 14.03.2010
comment
@Potatos, поэтому, когда выдает последний инициализированный конструктор члена, что вы должны делать в своем улове? Вы не можете отремонтировать его, поскольку рассматриваемый объект сделал бы это сам, если бы мог (он, безусловно, имеет больше знаний о себе). Вы можете просто уйти в отставку и позволить исключению уйти. Так что бы он вам купил, если бы вы могли получить доступ к другим участникам? Обратите внимание, что деструкторы других членов вызываются автоматически, если выбрасывается более поздний инициализированный член. Так что все чисто убрано. - person Johannes Schaub - litb; 14.03.2010
comment
@Johannes: Мы можем предположить, что метательный объект может быть несущественным. С другой стороны, знание частично сконструированного состояния может быть полезно для отладки вывода. Я думаю, что, вероятно, проще реализовать запуск блока catch после уничтожения ранее инициализированных членов, чем уничтожать их после повторного вызова. Я не говорю, что это большое дело, но могу представить, как это приведет к разочарованию. - person Potatoswatter; 14.03.2010

В C ++ есть механизм для этого, но он используется редко. Это функциональный блок try:

Bar::Bar()
try
  : Foo(1)
{
}
catch( Something )
{
}

См. Этот классический gotw, в котором объясняется, почему его следует использовать только для преобразования исключений (например, тип исключения FooException становится BarException).

person Todd Gardner    schedule 14.03.2010

Я считаю, что это должно быть обнаружено процедурой создания объекта.

person Spencer Ruport    schedule 14.03.2010