Lors d'un nouvel emploi, les critiques de code correspondant à ce code me sont signalées:
PowerManager::PowerManager(IMsgSender* msgSender)
: msgSender_(msgSender) { }
void PowerManager::SignalShutdown()
{
msgSender_->sendMsg("shutdown()");
}
On me dit que la dernière méthode devrait se lire:
void PowerManager::SignalShutdown()
{
if (msgSender_) {
msgSender_->sendMsg("shutdown()");
}
}
c'est-à-dire que je dois mettre un NULLgarde autour de la msgSender_variable, même s'il s'agit d'un membre de données privé. Il m'est difficile de m'empêcher d'utiliser des jurons pour décrire ce que je ressens à propos de cette «sagesse». Lorsque je demande une explication, je reçois toute une série d'histoires d'horreur sur la façon dont un programmeur junior, une année sur l'autre, s'est confondu sur la façon dont une classe était censée fonctionner et a accidentellement supprimé un membre qu'il ne devrait pas avoir (et l'a mis NULLensuite à , apparemment), et les choses ont explosé dans le champ droit après une sortie du produit, et nous avons « appris à la dure, faites- nous confiance » qu'il est préférable de simplement NULLvérifier tout .
Pour moi, cela ressemble à une programmation culte de la cargaison , tout simplement. Quelques collègues bien intentionnés essaient sincèrement de m'aider à «comprendre» et voient comment cela m'aidera à écrire un code plus robuste, mais ... je ne peux m'empêcher de penser que ce sont eux qui ne comprennent pas. .
Est-il raisonnable pour une norme de codage d'exiger que chaque pointeur déréférencé dans une fonction soit vérifié en NULLpremier, même pour les données privées? (Remarque: pour donner un certain contexte, nous fabriquons un dispositif électronique grand public, et non un système de contrôle du trafic aérien ou un autre produit «échec = égalité de personnes».)
EDIT : Dans l'exemple ci-dessus, le msgSender_collaborateur n'est pas facultatif. Si c'est le cas NULL, cela indique un bug. La seule raison pour laquelle il est passé au constructeur est qu'il PowerManagerpeut être testé avec une IMsgSendersous-classe fictive .
SOMMAIRE : Il y avait de très bonnes réponses à cette question, merci à tous. J'ai accepté celui de @aaronps principalement en raison de sa brièveté. Il semble y avoir un accord général assez large sur ce qui suit:
- Mandater des
NULLgardes pour chaque pointeur déréférencé est excessif, mais - Vous pouvez éviter tout le débat en utilisant une référence (si possible) ou un
constpointeur, et assertles instructions sont une alternative plus éclairée que lesNULLgardes pour vérifier que les conditions préalables d'une fonction sont remplies.
nullet ne rien faire n'est qu'un moyen de déplacer le bogue vers le bas de l'exécution, ce qui rend beaucoup plus difficile le suivi de la source.