2010-04-21 5 views
7

Dostaję błąd, który mówi:luźniejsze rzut specifier w C++

błąd: luźniejsze specifier rzut do 'wirtualnego CPLAT :: CP_Window :: ~ CP_Window()'

Na destructor, mam Nigdy wcześniej o tym nie słyszałem, a niektóre Wyszukiwania Google mówią, że może to być problem z GCC 4, którego nie byłbym pewien, jak obejść, ponieważ potrzebuję GCC 4 do zbudowania Universal Binary.

Moje środowisko: OS X 10.6, XCode 3.2.2, GCC 4, aby zbudować uniwersalny plik binarny.

Na czym polega problem?

Odpowiedz

12

Zakładam, że CPLAT ma klasę podstawową? Zgaduję również, że nie umieściłeś specyfikatora rzutowania na destruktorze CPLAT?

Można wstawić throw(X) (gdzie X jest listą wyjątków oddzielonych przecinkami) na końcu sygnatury funkcji, aby wskazać wyjątki, które wolno rzutować. Jeśli umieścisz throw() jako specyfikator rzutowania, oznacza to, że z tej funkcji nie można zgłaszać żadnych wyjątków. Powszechnie jest to robić z destruktorami, ponieważ nie chcesz, aby destruktor wyrzucał wyjątek.

Klasa, która zastępuje funkcję, która ma specyfikator rzutowania, nie może mieć luźnego specyfikatora rzutowania (podać więcej wyjątków) niż funkcja, która jest nadpisywana, ponieważ oznaczałoby to, że funkcja klasy pochodnej mogła naruszać specyfikator rzutowania bazy funkcja klasy. Brak specyfikatora rzutów oznacza, że ​​każdy wyjątek może zostać odrzucony z tej funkcji, więc jest tak luźny, jak to tylko możliwe.

Najprawdopodobniej trzeba dodać throw() na końcu sygnatury funkcji destruktora CPLAT.

Edit: Nawiasem mówiąc, powinienem chyba dodawać, że prawdopodobnie nie chcesz używać specyfikatorów rzucać (inne niż throw() na destruktorów) nie wiedząc, że to, co chcesz. W przeciwieństwie do sprawdzanych wyjątków Java, nie są one przechwytywane podczas kompilacji, ale raczej kończą program w momencie wykonania, jeśli zostaną naruszone. Najlepiej nie używać ich, chyba że wiesz, co robisz.

+2

Moja implementacja stl deklaruje std :: destruktor wyjątku jako '' wyjątek() throw(); ' Teraz jeśli idę i używam tego jako bazy dla własnych wyjątków, muszę zadeklarować desktruktor w każdej wyprowadzonej klasa, nawet jeśli nie ma nic do zrobienia w tym destruktorze, ponieważ jeśli nie, to narzeka gcc. Czy istnieje sposób na uniknięcie tej zbędnej deklaracji? –

+2

Nie o tym wiem, jeśli nic więcej, ponieważ technicznie nie jest to zbyteczne. Jeśli nie zdefiniujesz destruktora, otrzymasz taki, który nie ma specyfikatora rzutowania. Ma więc złą sygnaturę funkcji. Musisz nadać mu prawidłowy podpis funkcji, definiując go za pomocą pustego specyfikatora rzutowania: 'throw()'. Byłoby miło, gdyby kompilator właśnie to zrobił dla ciebie, ale to nie jest tak mądre, jak się wydaje. –

+0

Dzięki za komentarz. –