C++ Exceptions et héritage de std:: exception

compte tenu de ce code d'échantillon:

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

j'obtiens le résultat suivant:

Exception: unknown

tout simplement faire l'héritage de my_exception_tstd::exceptionpublic, j'obtiens le résultat suivant:

Exception: Hello, world!

quelqu'un Pourrait-il m'expliquer pourquoi le type de questions d'héritage dans ce cas? Points Bonus pour une référence dans la norme.

11
demandé sur Deduplicator 2010-04-03 04:02:57

2 réponses

lorsque vous héritez en privé, vous ne pouvez pas convertir ou accéder à cette classe de base en dehors de la classe. Depuis que vous avez demandé quelque chose de la norme:

§11.2/4:

Une classe de base est dite accessible si un membre public inventé de la classe de base est accessible. Si une classe de base est accessible, on peut implicitement convertir un pointeur en classe dérivée en pointeur vers cette classe de base (4.10, 4.11).

simplement dit, à rien en dehors de la classe, c'est comme vous n'avez jamais hérité de std::exception, parce que c'est privé. Ergo, il ne sera pas en mesure d'être pris dans le std::exception& clause, puisqu'il n'y a pas de conversion.

20
répondu GManNickG 2010-04-03 00:23:55

quelqu'un Pourrait-il m'expliquer pourquoi le type de questions d'héritage dans ce cas? Les points de Bonus pour un référence de la norme.

le type d'héritage n'a pas d'importance. Il importe seulement que vous ayez une conversion accessible disponible à l'un des types de capture. Il se trouve que depuis qu'il n'est pas publique l'héritage public n'est pas accessible conversion.


Explication:

Vous pouvez voir le même problème ici:

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

une exception lancée n'est capturée par un bloc catch que si:

  1. le bloc catch a un type correspondant, ou
  2. Le bloc catch est pour un type qui a un accessible conversion
  3. Le bloc catch est un catch...)
9
répondu Brian R. Bondy 2010-04-03 00:26:10