In un nuovo lavoro, sono stato segnalato nelle recensioni di codice per codice come questo:
PowerManager::PowerManager(IMsgSender* msgSender)
: msgSender_(msgSender) { }
void PowerManager::SignalShutdown()
{
msgSender_->sendMsg("shutdown()");
}
Mi è stato detto che l'ultimo metodo dovrebbe leggere:
void PowerManager::SignalShutdown()
{
if (msgSender_) {
msgSender_->sendMsg("shutdown()");
}
}
vale a dire, mi deve mettere una NULLguardia attorno alla msgSender_variabile, anche se è un membro di dati privati. È difficile per me trattenermi dall'usare le imprecazioni per descrivere cosa provo per questo pezzo di "saggezza". Quando chiedo una spiegazione, ricevo una litania di storie dell'orrore su come un programmatore junior, qualche anno, si è confuso su come avrebbe dovuto funzionare una classe e cancellato accidentalmente un membro che non avrebbe dovuto (e lo ha impostato in NULLseguito , a quanto pare), e le cose sono esplose sul campo subito dopo il rilascio di un prodotto, e abbiamo "imparato nel modo più duro, fidati di noi" che è meglio NULLcontrollare tutto .
Per me, sembra una programmazione di culto del carico , chiara e semplice. Alcuni colleghi ben intenzionati stanno seriamente cercando di aiutarmi a "ottenerlo" e vedere come questo mi aiuterà a scrivere codice più robusto, ma ... Non posso fare a meno di sentirli come quelli che non lo capiscono .
È ragionevole che uno standard di codifica richieda che ogni singolo puntatore con riferimento a una funzione sia controllato per NULLprimo, anche per i membri di dati privati? (Nota: per dare un po 'di contesto, realizziamo un dispositivo elettronico di consumo, non un sistema di controllo del traffico aereo o qualche altro prodotto "fail-egals-people-die".)
EDIT : nell'esempio sopra, il msgSender_collaboratore non è facoltativo. Se mai NULL, indica un bug. L'unico motivo per cui viene passato nel costruttore è quindi PowerManagerpuò essere testato con una IMsgSendersottoclasse finta .
SINTESI : Ci sono state delle risposte davvero fantastiche a questa domanda, grazie a tutti. Ho accettato quello di @aaronps principalmente per la sua brevità. Sembra esserci un accordo generale abbastanza ampio sul fatto che:
- Il mandato di
NULLguardia per ogni singolo puntatore senza riferimenti è eccessivo, ma - Puoi fare un passo laterale dell'intero dibattito usando invece un riferimento (se possibile) o un
constpuntatore e assertle dichiarazioni sono un'alternativa più illuminata alleNULLguardie per verificare che siano soddisfatte le condizioni preliminari di una funzione.
nulle non fare nulla è solo un modo per spostare il bug sull'esecuzione, rendendo molto più difficile rintracciare la fonte.