std::exception не ловит исключения наследника

320
30 января 2017, 18:00

Собственно:

#include <iostream>
class Exception : std::exception
{
public:
    Exception(const std::string &&whatStr) noexcept : whatStr(std::move(whatStr)) { }
    Exception(const std::string &whatStr) noexcept : whatStr(whatStr) { }
   ~Exception() noexcept=default;
    const char* what() const noexcept override
    {
        return whatStr.c_str();
    }
private:
    std::string whatStr;
};

int main(int argc, char *argv[])
{
    try
    {
      throw Exception("hello");
    }
    catch(std::exception& e)
    {
        std::cout<< e.what();
    }
    return 0;
}

Так происходит std::terminate, потому что exception& e не ловит Exception. Если добавить:

  catch(Exception& e)
    {
        std::cout<< e.what();
    }

То он понятное дело ловит. Но, почему не ловит базовый класс?

Answer 1

Предположу, проблема в том, что ваше наследование не публичное.

Попробуйте так:

class Exception : public std::exception

Только при открытом (public) наследовании код, обрабатывающий исключения, знает о том, что Exception — потомок std::exception.

Обязательная нормативная ссылка: стандарт явно требует публичного наследования:

the handler is of type cv T or cv T& and T is an unambiguous public base class of E [...]

Это, кстати, означает, что без публичного наследования код с отловом исключений не будет работать даже в функциях-членах класса Exception.

Answer 2

Читайте предупреждения компилятора, они рулез :)

VC++:

test.cpp(28): warning C4673: при передаче "Exception" следующие типы не будут рассматриваться на сайте получателя
test.cpp(28): warning C4670: exception: этот базовый класс недоступен

exception: этот базовый класс недоступен
Как справедливо заметил @VladD, нужно public-наследование

READ ALSO
Как выгрузить с .txt в Mysql?

Как выгрузить с .txt в Mysql?

Здравствуйте, столкнулся с такой проблемой:

347
Mysql не работает ограничение целостности check constraint

Mysql не работает ограничение целостности check constraint

Пытаюсь запретить записывать нулевые значения в поле datetime

332