2015-12-22 13 views
7

Wyjątki są dużą częścią C++ i jednym z powodów ich używania (wiem, że jest wiele, ważniejszych, z innych powodów) jest unikanie niepotrzebnych kontroli, które zaciemniają kod z wieloma instrukcjami if (może to jest niepoprawne założenie?).Dlaczego dereferencja std :: shared_ptr nie generuje wyjątku wskaźnika pustego (lub podobnego)?

Więc teraz jestem ciekawy, dlaczego std::shared_ptr::operator* i std::shared_ptr::operator-> nie rzucać null_ptr_exception lub podobne?

+0

Znalazłeś wdrożenie inteligentnego wskaźnika, dokłada opisanego zachowania ? – aggsol

+0

@aggsol, nie, skończyło się na tym, że robimy własne przy użyciu istniejących zasad implementacji i szablonów. – Samaursa

Odpowiedz

7

Rozumiem, że klasy inteligentnych wskaźników mają wyglądać i zachowywać się jak surowe wskazówki. Biorąc pod uwagę tę wiodącą rolę w projektowaniu, idealnie przestarzały kod mógłby po prostu zastąpić użycie surowych wskaźników inteligentnymi wskaźnikami przy użyciu równoważnej semantyki własności, a kod działałby dokładnie tak, jak poprzednio.

Dlatego zmiana zachowania inteligentnych wskaźników dereferencyjnych nie powinna wykonywać żadnych dodatkowych sprawdzeń ani wyrzucać wyjątków (tj. Ponieważ surowe wskaźniki nie zachowują się w ten sposób).

Propozycja dodać inteligentne wskaźniki do standardu wskazuje tej decyzji projektowych (A Proposal to Add General Purpose Smart Pointers to the Library Technical Report):

III. Decyzje projektowe

Zasady

A. Ogólne

  1. „tak blisko Raw Wskaźniki to możliwe, ale nie bliżej”
+1

Dzięki za odpowiedź. Muszę przyznać, że przyczyna od komitetu standardowego nie jest zadowalająca.Jeśli zastąpimy starszy kod inteligentnymi wskaźnikami, wówczas 'null_ptr_exception' będzie nieobsługiwany, a program i tak się zepsuje (tak jak twierdzenie, chociaż udzielone bez rozwijania - to znowu, tak jak twierdzenie, ten wyjątek może zostać rozbity na przez debugger). – Samaursa

+1

@Samaursa Do wyłuskiwania wskaźnika zerowego wskaźnik zerowy wyzwala niezdefiniowane zachowanie, a program może wydawać się działać normalnie, ale rozumiem twój punkt widzenia i frustrację. –

4

Jeśli każdy dereferencja udostępnionego wskaźnika był wymagany do sprawdzenia pod kątem nullptr i warunkowo wyrzucił wyjątek, może wystąpić wiele nadmiarowych sprawdzeń, nadpisanie kodu i narzut. Jasne - optymalizator prawdopodobnie wyeliminuje niektóre z nich, ale wciąż ... Zamiast tego, programista powinien sprawdzić raz jeszcze wiele-dereferencji.

+0

Ale czy to nie jest argument za/przeciw wyjątkom/kodom błędów? – Samaursa

+1

@Samaursa: nie ... odwołanie do surowego wskaźnika lub inteligentnej wskazówki biblioteki standardowej jest dozwolone do wygenerowania kodu maszynowego, który zakłada, że ​​wskaźnik nigdy nie będzie nullptr - ten kod maszynowy będzie działał szybciej niż kod, który musi sprawdzić i uniknąć (dla tego samego przypadki non-nullptr) rozgałęzienia do kodu obsługi błędów. Brak sprawdzania/rozgałęzienia jest szybszy, niezależnie od tego, czy obsługa została osiągnięta przy użyciu wyjątku lub kodu błędu (które same mogą się różnić szybkością i rozmiarem kodu maszynowego). –

+0

Spodziewałbym się, że 'unique_ptr' zawiera asercję i' shared_ptr' (ponieważ jest już dość ciężkim obiektem z odwołaniem liczącym i śledzącym 'weak_ptr's) do' throw'. Niemniej jednak ma sens, ponieważ dereferencja wskaźnika jest niezwykle powszechną operacją. – Samaursa

Powiązane problemy