DerivedDerived dd;
if ( dd.Foo() == BB_OUT_OF_RANGE ) {
handle_error();
}
Обработка ошибок без исключений в С++
Пишу проект средних размеров (~100-150 файлов), одно из требований - не использовать исключения. Соответственно, приходится обрабатывать ошибки с помощью кодов возвращаемых функциями значений. Сначала я делал все коды ошибок статическими членами классов, чьи методы их возвращают, но сейчас понял, что появилось много дублирующих констант с одинаковыми именами - например, EOUT_OF_RANGE есть почти везде. Плюс если иерархия ветвится, тоже возникают наложения, да и писать все время ClassName::ERROR_CODE надоедает.
Как лучше поступить? Сделать файл errors.h, куда добавлять все ошибки всех компонентов? Это вроде нарушение независимости классов выходит. Описывать все ошибки иерархии константами в хидере самого базового класса? Тоже не очень здорово.
Посмотрите как сделано в разных C/C++ библиотеках, выберите приемлимое.
В любом случае, не выйдет одновременно брать из единого источника и совсем не зависеть от него.
Да, я тоже уже понял, что вряд ли удастся найти универсальное решение и усидеть на двух стульях: сохранить автономность классов и одновременно избежать дублирования ошибок. Сейчас под рукой только исходники хромиума, а там черт ногу сломит), на выходных еще что-нибудь поковыряю)
Например классы: GG, TT
GG_logic_error;
GG_domain_error;
GG_invalid_argument;
GG_length_error;
GG_out_of_range;
TT_logic_error;
TT_domain_error;
TT_invalid_argument;
TT_length_error;
TT_out_of_range;
по-моему префикс не нужен и вот почему: допустим, есть иерархия Base <- Derived <- DerivedDerived. В класса Base наверняка есть OUT_OF_RANGE, и наверняка она есть в обоих потомках. Тогда при работе с потомком придется проверять
Код:
Т.е. при вызове потомка мы анализируем ошибки с префиксом предка, что нелогично. Если переопределять все коды ошибок в каждом классе, избыточность получается очень большой.
Я пока что остановился на том, что определяю все ошибки иерархии в самом базовом классе. Избыточность не очень велика, но при каждом добавлении нового класса приходится изменять заголовок базового, что не есть хорошо. Поищи еще проекты на C++, где не используют исключений, может быть там найду какие-нибудь идеи.