Konwencjonalny sposób rzut złapać wyjątków jest rzut obiektu wyjątku i złapać ją odniesienia (zwykle const
odniesienia). Język C++ wymaga, aby kompilator generował odpowiedni kod w celu skonstruowania obiektu wyjątku i właściwego czyszczenia go we właściwym czasie.
rzucanie wskaźnik do dynamicznie przydzielonego obiektu nigdy nie jest dobrym pomysłem. Wyjątki mają na celu umożliwienie pisania bardziej odpornego kodu w obliczu błędów. Jeśli rzucasz obiekt wyjątkowy w konwencjonalny sposób, możesz być pewien, że niezależnie od tego, czy zostanie on złapany przez klauzulę catch nazwaną właściwym typem, przez catch (...)
, czy zostanie on ponownie zgłoszony, czy nie, zostanie odpowiednio zniszczony we właściwym czasie. . (Jedynym wyjątkiem jest sytuacja, w której nigdy nie zostanie złapany, ale jest to sytuacja nie do naprawienia niezależnie od tego, jak na nią patrzysz.)
Jeśli rzucisz wskaźnik na dynamicznie przydzielany obiekt, musisz mieć pewność, że stos wywołań wygląda tak, jak w punkcie, w którym chcesz rzucić wyjątek, znajduje się blok catch, który nazywa właściwy typ wskaźnika i ma odpowiednie wywołanie delete
.Twój wyjątek nigdy nie może zostać przechwycony przez catch (...)
, chyba że ten blok ponownie rzuci wyjątek, który następnie zostanie przechwycony przez inny blok catch, który zajmuje się tym wyjątkiem.
Oznacza to, że skorzystałeś z funkcji obsługi wyjątków, która powinna ułatwić pisanie niezawodnego kodu i bardzo utrudnić pisanie kodu, który jest poprawny we wszystkich sytuacjach. Pozostawia to poza kwestią, że prawie niemożliwe będzie działanie jako kod biblioteki dla kodu klienta, który nie będzie oczekiwał tej funkcji.
Myślę, że "throw gcnew" przydałoby się np. jeśli chcesz, aby kod zarządzany przechwytywał twój wyjątek. Czy ktoś może mi to poprawić? – jpalecek
.Net zajmuje się wyjątkami za pomocą wskaźnika, więc polecenie gcnew jest właściwym rozwiązaniem. –
@SebastianRedl .Net "wskaźnik" może być niejednoznaczny? Chociaż gcnew na pewno nie jest. 'System :: Exception' jest ogólnie odniesieniem do zarządzanego obiektu na stadzie zbierającym śmieci. Zawsze byłem rzucany przez 'gcnew' i złapany przez' System :: Exception^'. Oczywiście używam 'finally' przez cały czas w C++/CLI, chociaż nie często łączę się z wyjątkami C++ w tym samym bloku' try', nie jestem pewien dlaczego. –