Actually:

#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; } 

So std::terminate happens, because exception& e does not catch Exception . If add:

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

That he understandably catches. But why not catch the base class?

    2 answers 2

    I suppose the problem is that your inheritance is not public.

    Try this:

     class Exception : public std::exception 

    Only with open ( public ) inheritance, the code that handles exceptions is aware that Exception is a descendant of std::exception .


    Mandatory normative reference : the standard clearly requires public inheritance:

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

    This, by the way, means that without public inheritance, code with catching exceptions will not work even in member functions of the Exception class.

      Read the compiler warnings, they rulez :)

      VC ++:

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

      exception: this base class is not available
      As @VladD rightly noted, public inheritance is needed

      • mingw, unfortunately, was silent about that - bronstein87
      • What is the default warning? I highly recommend to include them - most simple mistakes (typos, etc.) are caught immediately. - Harry
      • -Wpedantic -Wall -Wextra included, seemingly even more and nothing - bronstein87