C++ classe d'exception de conception

Qu'est ce qu'un bon design pour un ensemble de classes d'exception?

Je vois toutes sortes de choses autour de quelles classes d'exception qui devrait et ne devrait pas le faire, mais pas une conception simple qui est facile à utiliser et d'étendre choses.

  1. Les classes d'exception ne devrait pas lancer des exceptions, car cela pourrait l'amener tout droit à la résiliation de ce processus sans aucune possibilité de se connecter à l'erreur, etc.
  2. Il doit être possible d'obtenir une interface utilisateur conviviale de la chaîne, de préférence localisée à leur langue, de sorte qu'il ya quelque chose à leur dire avant de fermer l'application elle-même si elle ne peut pas récupérer d'une erreur.
  3. Il doit être possible d'ajouter des informations comme la pile se déroule, par exemple, si un analyseur XML ne parvient pas à analyser un flux d'entrée, pour être en mesure d'ajouter que la source était à partir d'un fichier, ou sur le réseau, etc.
  4. Des gestionnaires d'Exception besoin d'accéder facilement à l'information dont ils ont besoin pour gérer l'exception.
  5. Écrire formaté à l'exception des informations dans un fichier journal (en anglais, pas de traduction ici).

De 1 et 4, de travailler ensemble est le plus gros problème que je vais avoir, depuis la mise en forme et de sortie de fichier méthodes pourraient éventuellement échouer.

EDIT:
Donc, après avoir regardé des classes d'exception en plusieurs classes, et aussi dans la question Neil liés à, il semble être de pratique courante, à juste complètement ignorer le point 1 (et donc le coup de pouce des recommandations), ce qui semble être une assez mauvaise idée de moi.

De toute façon, j'ai pensé que je pourrais aussi poster l'exception de la classe, je suis en train de penser à l'aide.

class Exception : public std::exception
{
    public:
        //Enum for each exception type, which can also be used
        //to determine the exception class, useful for logging
        //or other localisation methods for generating a
        //message of some sort.
        enum ExceptionType
        {
            //Shouldn't ever be thrown
            UNKNOWN_EXCEPTION = 0,

            //The same as above, but it has a string that
            //may provide some information
            UNKNOWN_EXCEPTION_STR,

            //For example, file not found
            FILE_OPEN_ERROR,

            //Lexical cast type error
            TYPE_PARSE_ERROR,

            //NOTE: in many cases functions only check and
            //      throw this in debug
            INVALID_ARG,

            //An error occured while trying to parse
            //data from a file
            FILE_PARSE_ERROR,
        }

        virtual ExceptionType getExceptionType()const throw()
        {
            return UNKNOWN_EXCEPTION;
        }

        virtual const char* what()throw(){return "UNKNOWN_EXCEPTION";}
};


class FileOpenError : public Exception
{
    public:
        enum Reason
        {
            FILE_NOT_FOUND,
            LOCKED,
            DOES_NOT_EXIST,
            ACCESS_DENIED
        };
        FileOpenError(Reason reason, const char *file, const char *dir)throw();
        Reason getReason()const throw();
        const char* getFile()const throw();
        const char* getDir ()const throw();

    private:
        Reason reason;
        static const unsigned FILE_LEN = 256;
        static const unsigned DIR_LEN  = 256;
        char file[FILE_LEN], dir[DIR_LEN];
};

Point 1 est réglé, étant donné que toutes les chaînes sont gérées par la copie d'un interne, fixe la taille de la mémoire tampon (troncature si nécessaire, mais toujours null).

Bien que ce n'est pas l'adresse de point 3, mais je pense que le point est plus que probable de l'utilisation limitée dans le monde réel, de toute façon, et ils sont les plus susceptibles d'être abordés en lançant une nouvelle exception en cas de besoin.

InformationsquelleAutor Fire Lancer | 2009-08-26