Co to jest dobry projekt dla zestawu klas wyjątków? Widzę różnego rodzaju rzeczy wokół tego, co klasy wyjątków powinny i nie powinny robić, ale nie prosty projekt, który jest łatwy w obsłudze i rozszerzeniu, który robi te rzeczy.C++ Projektowanie klasy wyjątków
- Klasy wyjątków nie należy rzucać wyjątków, ponieważ może to prowadzić prosto do zakończenia procesu bez możliwości zalogowania błąd itd
- To musi być możliwe, aby uzyskać przyjazne dla użytkownika ciąg znaków, preferowane zlokalizowane na ich język, tak aby było coś do powiedzenia, zanim aplikacja zakończy działanie, jeśli nie będzie w stanie naprawić błędu.
- Musi istnieć możliwość dodawania informacji podczas rozwijania stosu, np. Jeśli parser xml nie przeanalizuje strumienia wejściowego, aby można było dodać, że źródło pochodziło z pliku lub przez sieć itp.
- Programy obsługi wyjątków potrzebują łatwego dostępu do informacji potrzebnych do obsługi wyjątku.
- Zapisuj sformatowane informacje o wyjątku do pliku dziennika (w języku angielskim, więc nie ma tu tłumaczeń).
Pierwsze 1 i 4 do wspólnej pracy to największy problem, jaki mam, ponieważ wszelkie metody formatowania i plików mogą potencjalnie zawieść.
EDYCJA: Tak więc po zapoznaniu się z klasami wyjątków w kilku klasach, a także w pytaniu, z którym związany jest Neil, wydaje się, że powszechną praktyką jest po prostu całkowite zignorowanie punktu 1 (i tym samym zaleceń doładowania), który wydaje się być raczej zły pomysł dla mnie.
W każdym razie myślałem, że id również opublikuję klasę wyjątków, którą zamierzam użyć.
class Exception : public std::exception
{
public:
//enum for each exception type, which can also be used to determin
//exception class, useful for logging or other localisation methods
//for generating a message of some sort.
enum ExceptionType
{
//shouldnt ever be thrown
UNKNOWN_EXCEPTION = 0,
//same as above but has a string that may provide some info
UNKNOWN_EXCEPTION_STR,
//eg 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];
};
Punkt 1 jest skierowana ponieważ wszystkie ciągi są obsługiwane przez kopiowanie do wewnętrznego bufora, ustalonej wielkości (obcinanie, jeśli to konieczne, ale zawsze null zakończone).
Mimo że nie dotyczy to punktu 3, myślę, że punkt ten najprawdopodobniej ma ograniczone zastosowanie w realnym świecie i najprawdopodobniej zostanie rozwiązany przez zgłoszenie nowego wyjątku w razie potrzeby.
Ten? http://stackoverflow.com/questions/1157591/c-exception-handling – GManNickG
To był ten, o którym myślałem, chociaż ponownie go czytałem, wydaje się, że odpowiada na nieco inne pytania. –
Co jest nie tak z różnymi klasami? Możesz obsługiwać je inaczej, a nawet obsługiwać niektóre i pozostawiać innych. –