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 NULL
garde 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 NULL
ensuite à , 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 NULL
vé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 NULL
premier, 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 PowerManager
peut être testé avec une IMsgSender
sous-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
NULL
gardes 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
const
pointeur, et assert
les instructions sont une alternative plus éclairée que lesNULL
gardes pour vérifier que les conditions préalables d'une fonction sont remplies.
null
et 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.