J'écris une petite hiérarchie de classes d'exception pour une application C++ je développe, et je vais avoir du mal à tirer indirectement de std::runtime_error
. Voici le code analogue à ce que j'ai écrit jusqu'à présent:classe Dérivant de base virtuelle sans constructeur par défaut
class RuntimeException : public virtual boost::exception, public virtual std::runtime_error {
public:
virtual ~RuntimeException() {}
RuntimeException() : runtime_error("A RuntimeException occurred.") {}
RuntimeException(const std::string& what) : runtime_error(what) {}
};
class IllegalArgumentException : public virtual RuntimeException {
public:
IllegalArgumentException() : RuntimeException("An IllegalArgumentException occurred.") {}
IllegalArgumentException(const std::string& what) : RuntimeException(what) {}
};
La classe RuntimeException
compile sans problème, mais IllegalArgumentException
refuse de compiler sur VS2015, générant l'erreur: no default constructor exists for class "std::runtime_error"
pour les deux constructeurs de IllegalArgumentException
. Cela remet en cause ma compréhension des hiérarchies d'héritage C++, car je m'attendais à ce que ce code compile bien.
Ma compréhension est que IllegalArgumentException
devrait compilez parce que, bien qu'il est vrai que std::runtime_error
n'a pas de constructeur par défaut, son constructeur est appelé par le constructeur pour RuntimeException
. Mais évidemment, ce doit être faux, car le compilateur le rejette. Il semble vouloir que j'appelle le constructeur std::runtime_error
directement du constructeur IllegalArgumentException
(l'erreur de compilateur disparaît quand je le fais), mais cela semble faux car alors j'appellerais le constructeur pour std::runtime_error
deux fois: une fois dans le constructeur pour RuntimeException
, et encore dans le constructeur pour IllegalArgumentException
.
Est-ce sécuritaire et/ou efficace de faire? Si non, pourquoi le compilateur semble-t-il l'encourager? Je pourrais tirer juste de std::exception
et mettre en œuvre moi-même std::string
comme une variable membre, mais je pensais que ce serait plus facile de tirer d'une classe standard qui a déjà mis en oeuvre. Est-ce la mauvaise approche à adopter? En outre, le fait que je suis à la fois tirer pratiquement boost:exception
et std::runtime_error
contribuer à cette question?
Merci pour cela, votre explication est très claire. À la lumière de cela, je vais très probablement finir par dériver de 'std :: exception' et utiliser mon propre' std :: string'. Cela semble le moyen le plus simple d'y aller. –