Почему программисты используют как std :: bad_alloc, так и std :: exception.Является ли std :: исключение одним недостаточно - PullRequest
0 голосов
/ 18 октября 2018

Рассмотрим следующий фрагмент кода

try {
    goesWrong();
}
catch (const std::bad_alloc &e)
{
    std::cout << "Catching bad_alloc: " << e.what() << std::endl;
}
catch (const std::exception &e)
{
    std::cout << "Catching exception: " << e.what() << std::endl;
}

Почему нам нужно отлавливать множество отдельных исключений.Просто std::exception в конце достаточно, чтобы поймать все исключения, не так ли?Зачем дополнительные 4 строки кода, чтобы явно ловить std::bad_alloc, когда std::exception все равно его поймает?

Ответы [ 4 ]

0 голосов
/ 18 октября 2018

Более дополнение к ответам, данным до сих пор, чем отдельный, собственный:

На самом деле, вы могли бы основывать обработку исключений на оценке строки what():

catch(std::exception const& e)
{
    if(strcmp(e.what(), "some text"))
    {
        doThis();
    }
    else if(strstr(e.what(), "something"))
    {
        doThat();
    }
    // ...
}

Однако для этого необходимо знать точное содержимое строки.Что, если они различаются в разных реализациях C ++?Что, если они локализованы в некоторых системах?Вы действительно хотите справиться со всеми такими вопросами?Кроме того, обработка текста намного дороже, чем просто перехват различных исключений.

Таким образом, с различными исключениями вы получаете мобильность, безопасность (рассмотрите опечатки в строках, с которыми вы сравниваете ...), более простой и лучший читаемый код и, в качестве бонуса, эффективность.

0 голосов
/ 18 октября 2018

Почему нам нужно отлавливать множество отдельных исключений.

В общем, потому что это допускает различное поведение в зависимости от типа перехваченного исключения.

В этом случае это необходимо сделать, поскольку эта возможность не используется.

Рассмотрим, например, случай, когда вы выделили большой кэш в памяти.В этом случае при перехвате std::bad_alloc вы можете освободить кеш и повторить попытку, хотя этот подход не будет полезен в случае других исключений.

0 голосов
/ 18 октября 2018

Отдельные операторы catch имеют различное поведение в зависимости от типа создаваемого исключения.

Например, вы можете ожидать bad_alloc и можете восстановить его, повторив попытку с меньшимвыделение или освобождение памяти в другом месте.

Достаточно просто std :: исключение в конце, чтобы перехватить все исключения, не так ли?

Нет, перехват std::exceptionдостаточно, чтобы перехватить все сгенерированные исключения, полученные из std::exception.В c ++ std::exception нет особого значения, вы можете выбросить любой тип в качестве исключения.Рекомендуется наследовать от std::exception, но не обязательно.

Существуют даже ловушки, например, если у вас множественное наследование и ваш класс исключений получается из std::exception , дважды он не будет пойман .

Чтобы поймать все исключения, вам нужно поймать ...:

struct my_exception {};

try
{
  switch ( i )
  {
  case 1:
    throw std::runtime_error( "i is 1" );
  case 2:
    // bad idea, who is responsible for freeing the exception? But perfectly legal
    throw new std::runtime_error( "i is 1" );
  case 3:
    // you can throw numbers too
    throw i;
  case 4:
    throw my_exception();
  }
}
catch ( const std::exception& )
{
}
catch ( const my_exception& )
{
}
catch ( ... )
{
}
0 голосов
/ 18 октября 2018

exception может быть любым исключением, в то время как bad_alloc более конкретно.Вы можете не только по-разному реагировать на различные исключения, но и более четко выражать происходящее.В конце концов, код написан, чтобы выразить ваше намерение, а не просто заставить его работать как-то.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...