С++ для начинающих



         

Конструкторы и функциональные try-блоки


Можно объявить функцию так, что все ее тело будет заключено в try-блок. Такие try-блоки называются функциональными. (Мы упоминали их в разделе 11.2.) Например:

int main() {

try {

   // тело функции main()

}

catch ( pushOnFull ) {

   // ...

}

catch ( popOnEmpty ) {

   // ...

}

Функциональный try-блок ассоциирует группу catch-обработчиков с телом функции. Если инструкция внутри тела возбуждает исключение, то поиск его обработчика ведется среди тех, что следуют за телом функции.

Функциональный try-блок необходим для конструкторов класса. Почему? Определение конструктора имеет следующий вид:

имя_класса( список_параметров )

// список инициализации членов:

: член1(выражение1 ) ,    // инициализация член1

  член2(выражение2 ) ,    // инициализация член2

// тело функции:

{ /* ... */ }

выражение1 и выражение2 могут быть выражениями любого вида, в частности функциями, которые возбуждают исключения.

Рассмотрим еще раз класс Account, описанный в главе 14. Его конструктор можно переопределить так:

inline Account::

Account( const char* name, double opening_bal )

       : _balance( opening_bal - ServiceCharge() )

{

   _name = new char[ strlen(name) + 1 ];

   strcpy( _name, name );

   _acct_nmbr = get_unique_acct_nmbr();

}

Функция ServiceCharge(), вызываемая для инициализации члена _balance, может возбуждать исключение. Как нужно реализовать конструктор, если мы хотим обрабатывать все исключения, возбуждаемые функциями, которые вызываются при конструировании объекта типа Account?

Помещать try-блок в тело функции нельзя:

inline Account::

Account( const char* name, double opening_bal )

       : _balance( opening_bal - ServiceCharge() )

{

   try {

      _name = new char[ strlen(name) + 1 ];

      strcpy( _name, name );

      _acct_nmbr = get_unique_acct_nmbr();

   }

   catch (...) {

      // специальная обработка

      // не перехватывает исключения,

      // возбужденные в списке инициализации членов

   }

}

Поскольку try-блок не охватывает список инициализации членов, то catch-обработчик, находящийся в конце конструктора, не рассматривается при поиске кандидатов, которые способны перехватить исключение, возбужденное в функции ServiceCharge().




Содержание  Назад  Вперед