Przy nowej pracy dostaję oznaczenie w recenzjach kodu dla kodu w następujący sposób:
PowerManager::PowerManager(IMsgSender* msgSender)
: msgSender_(msgSender) { }
void PowerManager::SignalShutdown()
{
msgSender_->sendMsg("shutdown()");
}
Powiedziano mi, że ostatnia metoda powinna brzmieć:
void PowerManager::SignalShutdown()
{
if (msgSender_) {
msgSender_->sendMsg("shutdown()");
}
}
tzn. muszę ustawić NULL
osłonę wokół msgSender_
zmiennej, nawet jeśli jest ona prywatnym członkiem danych. Trudno mi powstrzymać się od użycia przekleństw, aby opisać, co sądzę o tym „mądrości”. Kiedy proszę o wyjaśnienie, dostaję litanię horrorów o tym, jak jakiś młodszy programista, pewnego roku, pomylił się co do tego, jak klasa powinna działać, i przypadkowo usunął członka, którego nie powinien był (i ustawił NULL
później , najwyraźniej), a rzeczy wybuchły w terenie zaraz po wydaniu produktu, a my „nauczyliśmy się twardej drogi, zaufaj nam”, że lepiej po prostu wszystkoNULL
sprawdzić .
Dla mnie jest to programowanie z kultowym ładunkiem , proste i proste. Kilku współpracowników, którzy mają dobre intencje, poważnie stara się pomóc mi „zdobyć” i zobaczyć, jak to pomoże mi napisać bardziej solidny kod, ale ... Nie mogę się powstrzymać od poczucia, że to oni go nie rozumieją .
Czy rozsądne jest, aby standard kodowania wymagał, aby każdy wskaźnik odsunięty od funkcji w NULL
pierwszej kolejności był sprawdzany w pierwszej kolejności - nawet dla prywatnych członków danych? (Uwaga: aby nadać kontekstu, tworzymy elektronikę użytkową, a nie system kontroli ruchu lotniczego lub inny produkt „brak równości ludzi”).
EDYCJA : W powyższym przykładzie msgSender_
współpracownik nie jest opcjonalny. Jeśli kiedykolwiek NULL
, oznacza to błąd. Jedynym powodem, dla którego jest przekazywany do konstruktora, jest PowerManager
testowanie IMsgSender
podklasy próbnej.
STRESZCZENIE : Dziękuję wszystkim za naprawdę świetne odpowiedzi na to pytanie. Zaakceptowałem ten z @aaronps głównie ze względu na jego zwięzłość. Wydaje się, że istnieje ogólna zgoda co do tego, że:
- Nakazanie
NULL
strażnikom każdego odsuniętego wskaźnika jest przesadą, ale - Możesz przejść całą debatę na bok, używając zamiast tego odwołania (jeśli to możliwe) lub
const
wskaźnika i assert
instrukcje są bardziej oświeconą alternatywą dlaNULL
strażników do sprawdzania, czy spełnione są warunki wstępne funkcji.
null
i nic nie robienie jest tylko sposobem na przeniesienie błędu w dół wykonania, co znacznie utrudnia powrót do źródła.