Учитывая этот пример кода:
#include <iostream>
#include <stdexcept>
class my_exception_t : std::exception
{
public:
explicit my_exception_t()
{ }
virtual const char* what() const throw()
{ return "Hello, world!"; }
};
int main()
{
try
{ throw my_exception_t(); }
catch (const std::exception& error)
{ std::cerr << "Exception: " << error.what() << std::endl; }
catch (...)
{ std::cerr << "Exception: unknown" << std::endl; }
return 0;
}
Я получаю следующий вывод:
Exception: unknown
Все же просто делая наследование my_exception_t
от std::exception
public
, Я получаю следующий вывод:
Exception: Hello, world!
Кто-то мог объяснить мне, почему тип наследования имеет значение в этом случае? Бонусные очки для ссылки в стандарте.
Когда вы наследуете частным образом, вы не можете преобразовать или иным образом получить доступ к базовому классу вне класса. Поскольку вы просили что-то из стандарта:
§11.2/4:
Считается, что базовый класс доступен, если доступен придуманный открытый член базового класса. Если базовый класс доступен, то можно неявно преобразовать указатель на производный класс в указатель на этот базовый класс (4.10, 4.11).
Проще говоря, для чего-либо за пределами класса это все равно, что вы никогда не наследовались от std::exception
, потому что он приватный. Следовательно, оно не сможет быть поймано в std::exception&
, поскольку преобразования не существует.
Может ли кто-нибудь объяснить мне, почему тип наследования имеет значение в в этом случае? Бонусные очки за ссылку в стандарте.
Тип наследования не имеет значения. Имеет значение только то, что у вас есть доступное преобразование к одному из типов catch. Так получилось, что поскольку это не публичное наследование, то нет публичного доступного преобразования.
Объяснение:
Вы можете увидеть такое же поведение здесь:
class B
{
};
class C1 : B
{
};
class C2 : public B
{
};
int main(int argc, char** argv)
{
B& b1 = C1();//Compiling error due to conversion exists but is inaccessible
B& b2 = C2();//OK
return 0;
}
Брошенное исключение перехватывается блоком catch только если: