Создание пользовательских исключений в С++

Я изучаю С++, и я испытываю, когда пытаюсь создать собственное исключение и бросаю их в Linux.

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

class TestClass : public std::runtime_error
{
public:
    TestClass(char const* const message) throw();
    virtual char const* what() const throw();
};

Исходным файлом для класса исключения является

using namespace std;

TestClass::TestClass(char const* const message) throw()
    : std::runtime_error(message)
{

}

char const * TestClass::what() const throw()
{
    return exception::what();
}

В моем основном приложении я вызываю функцию, которая выдает мое исключение и ловит его в try/catch следующим образом:

void runAFunctionAndthrow();

/*
 * 
 */
int main(int argc, char** argv) {
    try
    {
        cout << "About to call function" << endl;
        runAFunctionAndthrow();
    }
    catch (TestClass ex)
    {
        cout << "Exception Caught: " << ex.what() << endl;
    }

    return 0;
}

void runAFunctionAndthrow()
{
    cout << "going to run now. oh dear I need to throw an exception" << endl;

    stringstream logstream;
    logstream << "This is my exception error. :(";
    throw TestClass(logstream.str().c_str());
}

Когда я запустил, я ожидаю получить следующий вывод:

О вызове функции

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

Exception Caught: Это моя ошибка исключения.: (

Вместо этого я получаю

О вызове функции

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

Исключение: Std:: exception

Обратите внимание, что в последней строке указано std:: exception вместо моего фактического сообщения об исключении "Это моя ошибка исключения".

Почему это, он работает нормально в Windows, но в Linux он это делает.

Из того, что я видел на разных постах, то, что я сделал, является правильным, так что мне не хватает.

Ответ 1

Ваш what() возвращает:

 return exception::what();

Возвращаемое значение из std::exception::what() указано следующим образом:

Указатель на строку с нулевым завершением с пояснительной информацией.

Что это. Ничего больше, больше ничего. Текст, который вы показываете, безусловно, квалифицируется как "пояснительная информация". И это единственное требование для возвращаемого значения what() (за исключением одного другого, который здесь не является родным).

Другими словами, С++ не гарантирует точное содержание того, что вы получаете с помощью what(). what() Вы видите, что what() вы получаете, как говорится.

Если вы хотите, чтобы ваше исключение описывало себя, каким-то образом, вам нужно реализовать это как часть вашего what().

Ответ 2

Вам нужна ваша реализация метода what() или используйте std::runtime_error::what(), как написано в комментариях

Скажи:

class TestClass : public std::runtime_error
{
    std::string what_message;
public:
    const char* what() override
    {
        return what_message.c_str();
    }
};

Кроме того, лучше использовать noexcept вместо throw() и только после того, как вы прочтете о них - ссылка.

И в вашем try-catch:

catch (const TestClass& myException)

Вместо catch(TestClass myException) - иначе вы делаете неявную копию, которая потенциально может привести к выбросу исключений. Он также разрушает полиморфизм: если вы хотите использовать экземпляр реализации catch pure virtual interface, вам нужно будет использовать ссылку.

Ответ 3

Вам нужен способ указать настраиваемое сообщение об ошибке для std:: exception, для которого afaik не разрешен. См. для возможного решения.