Различие: станд.:: runtime_error по сравнению со станд.:: исключение ()

Разработчик, который не заботится о стиле, похож на художника, живописца, который не заботится о цвете.

121
задан w.b 9 July 2014 в 08:51
поделиться

2 ответа

std :: exception - это класс, единственная цель которого - служить базовым классом в иерархии исключений. Другого применения он не имеет. Другими словами, концептуально это абстрактный класс (хотя он не определен как абстрактный класс в значении термина в C ++).

std :: runtime_error - более специализированный класс, происходящий от std :: exception , предназначенный для выдачи в случае различных ошибок времени выполнения . У него двойное назначение. Он может быть запущен сам по себе или может служить базовым классом для различных, даже более специализированных типов исключений ошибок времени выполнения, таких как std :: range_error , std :: overflow_error и т. Д. . Вы можете определить свои собственные классы исключений, производные от std :: runtime_error , а также вы можете определить свои собственные классы исключений, производные от std :: exception .

Как и std :: runtime_error , стандартная библиотека содержит std :: logic_error , также происходящий от std :: exception .

Смысл наличия этой иерархии - дать пользователю возможность использовать всю мощь механизма обработки исключений C ++. Поскольку предложение catch может перехватывать полиморфные исключения, пользователь может писать предложения catch, которые могут перехватывать типы исключений из определенного поддерева иерархии исключений. Например, catch (std :: runtime_error & e) перехватит все исключения из поддерева std :: runtime_error , позволяя всем остальным проходить через них (и лететь дальше по стеку вызовов).

PS Разработка полезной иерархии классов исключений (которая позволила бы вам перехватывать только те типы исключений, которые вам интересны в каждой точке вашего кода) - нетривиальная задача. То, что вы видите в стандартной библиотеке C ++, - это один из возможных подходов, предложенных вам авторами языка. Как видите, они решили разделить все типы исключений на «ошибки времени выполнения» и «логические ошибки» и позволить вам продолжить работу с вашими собственными типами исключений. Конечно, существуют альтернативные способы структурирования этой иерархии, которые могут быть более подходящими для вашего дизайна.

Обновление: переносимость Linux и Windows

Как отметили в своем ответе и комментариях ниже Локи Астари и unixman83, конструктор класс исключения не принимает никаких аргументов в соответствии со стандартом C ++. В Microsoft C ++ есть конструктор, принимающий аргументы из класса exception , но это не стандартно. Класс runtime_error имеет конструктор, принимающий аргументы ( char * ) на обеих платформах, Windows и Linux. Чтобы быть переносимым, лучше использовать runtime_error .

(И помните, что если в спецификации вашего проекта указано, что ваш код не должен работать в Linux, это не означает, что он никогда не должен работать в Linux.)

149
ответ дан 24 November 2019 в 01:33
поделиться

std :: exception следует рассматривать (обратите внимание на рассматриваемое) как абстрактную основу стандартной иерархии исключений. Это связано с тем, что нет механизма для передачи определенного сообщения (для этого вы должны получить и специализировать what ()). Ничто не мешает вам использовать std :: exception, а для простых приложений это может быть все, что вам нужно.

std :: runtime_error, с другой стороны, имеет допустимые конструкторы, которые принимают строку как сообщение. Когда вызывается what (), возвращается указатель const char, который указывает на строку C, которая имеет ту же строку, что была передана в конструктор.

try
{
    if (badThingHappened)
    {
         throw std::runtime_error("Something Bad happened here");
    }
}
catch(std::exception const& e)
{
    std::cout << "Exception: " << e.what() << "\n";
} 
18
ответ дан 24 November 2019 в 01:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: