Постарайтесь не резать типов исключительной ситуации (C++)

JavaScript:

function i(){ i(); }
i();

<час> C++ Используя указатель функции:
int main(){
   int (*f)() = &main;
   f();
}
5
задан Community 23 May 2017 в 11:45
поделиться

4 ответа

Я бы воздержался от разработки иерархии исключений, отличной от вашей библиотеки. По возможности используйте иерархию std :: exception , а всегда извлекайте исключения из чего-то в этой иерархии. Вы можете прочитать раздел об исключениях в разделе часто задаваемых вопросов по C ++ Маршалла Клайна - прочтите FAQ 17.6 , 17.9 , 17.10 и В частности, 17.12

Что касается «принуждения пользователей к поиску по ссылке» , я не знаю хорошего способа сделать это. Единственный способ, который я придумал за час или около того игры (это воскресенье днем), основан на полиморфном броске :

class foo_exception {
public:
    explicit foo_exception(std::string msg_): m_msg(msg_) {}
    virtual ~foo_exception() {}
    virtual void raise() { throw *this; }
    virtual std::string const& msg() const { return m_msg; }
protected:
    foo_exception(foo_exception const& other): m_msg(other.m_msg) {}
private:
    std::string m_msg;
};

class bar_exception: public foo_exception {
public:
    explicit bar_exception(std::string msg_):
        foo_exception(msg_), m_error_number(errno) {}
    virtual void raise() { throw *this; }
    int error_number() const { return m_error_number; }
protected:
    bar_exception(bar_exception const& other):
        foo_exception(other), m_error_number(other.m_error_number) {}
private:
    int m_error_number;
};

Идея состоит в том, чтобы сделать конструктор копирования защищенным и заставить пользователей вызовите Класс (аргументы). Raise () вместо throw Class (args) . Это позволяет вам генерировать полиморфно привязанное исключение, которое ваши пользователи могут перехватить только по ссылке. Любая попытка поймать по значению должна быть встречена красивым предупреждением компилятора. Что-то вроде:

foo.cpp: 59: error: 'bar_exception :: bar_exception (const bar_exception &)' защищено

foo.cpp: 103: error: в этом контексте

Конечно, все это происходит price, поскольку вы больше не можете использовать throw явно, иначе вы получите аналогичное предупреждение компилятора:

foo.cpp: в функции 'void h ()':

foo.cpp: 31 : error: 'foo_exception :: foo_exception (const foo_exception &)' защищен

foo.cpp: 93: error: в этом контексте

foo.cpp: 31: error: 'foo_exception :: foo_exception (const foo_exception &)' защищен

foo.cpp: 93: ошибка: в этом контексте

В целом, я бы полагался на стандарты кодирования и документацию, в которой говорится, что вы всегда должны ловить по ссылке. Убедитесь, что ваша библиотека перехватывает исключения, которые она обрабатывает по ссылке, и генерирует новые объекты (например, throw Class (constructorArgs) или throw; ). Я ожидал бы, что другие программисты на C ++ будут обладать такими же знаниями, но добавьте примечание к любой документации, чтобы быть уверенным.

6
ответ дан 18 December 2019 в 06:02
поделиться

У вашего исключения должен быть общедоступный конструктор копирования. Компилятор должен иметь возможность копировать его, чтобы обработка исключений работала.

Решение вашей проблемы состоит в том, чтобы вместо этого всегда выполнять поиск по ссылке:

try {
    // some code...
    throw MyException("lp0 is on fire!");
} catch (MyException const &ex) {
    // handle exception
}

( const -ness не является обязательным, но я всегда вставляйте его, потому что редко нужно изменять объект исключения.)

15
ответ дан 18 December 2019 в 06:02
поделиться

Я бы сказал, что не следует использовать какой-либо встроенный код исключений C ++. Если у вас должны быть исключения, создайте собственное с нуля. Это единственный способ убедиться, что они будут вести себя одинаково, не говоря уже о том, чтобы быть реализованными аналогичным образом, и, говоря прямо, реализация исключений в C ++ некомпетентна.

-3
ответ дан 18 December 2019 в 06:02
поделиться

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

9
ответ дан 18 December 2019 в 06:02
поделиться
Другие вопросы по тегам:

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