2009-06-24 8 views
7

Je suis à la recherche à un code (Delphi 7) avec vérification suivante est en haut de chaque appel de méthode pour un objet spécifique:Pourquoi vérifieriez-vous la présence de Assigned (self) dans les méthodes objet?

if not Assigned(self) then 
    raise Exception.CreateRes(@sAbstractError); 

    { Real code for this method} 

Je suppose que cela me empêcher d'essayer d'appeler une méthode sur un pointeur d'objet null. Mais j'obtiendrais une exception dès que j'aurais essayé d'accéder aux données des membres dans ce cas, n'est-ce pas?

Est-ce un type de norme que je n'ai jamais vu auparavant? L'objet en question dérive de TPersistent.

Répondre

8

Vous pouvez appeler une méthode d'instance sur un pointeur nul bien que ce ne soit pas le genre de chose que vous voulez faire délibérément. Lorsque cela se produit, l'exécution se poursuit assez heureusement jusqu'à ce qu'il ait besoin d'accéder aux données de l'instance, puis tout va bang.

Dans ce cas, la vérification de zéro vous alertera en haut de la procédure afin que vous puissiez faire quelque chose de différent, comme la consignation d'une trace de pile. Ou vous pouvez mettre un point de rupture sur la ligne de relèvement pour pouvoir plonger et voir ce qui se passe. Par exemple, c'est quelque chose que je pourrais faire si j'avais un bug spécifique que j'essayais de retrouver là où une référence nulle était utilisée.

Le faire régulièrement me semble une odeur de code.

4

Il existe des scénarios de violation d'accès pouvant entraîner l'exécution de code en mémoire lorsque Self est nul. Certains programmeurs, au lieu de résoudre le vrai problème, tentent de contourner l'utilisation de telles affirmations, pour éviter les corruptions de toutes sortes. Je vérifierais très bien si cette Exception augmente toujours en cours d'exécution, si c'est le cas - vous avez du code bogué sous vos mains. Vous pouvez lire l'article suivant sur le sujet suivant: When Self in Nil... You Know You are in Trouble.

Une autre possibilité est liée aux événements, vous pouvez lire plus ici, avec beaucoup d'exemples pour de tels tests, et les explications correspondantes: Multicast Events - Part 2.

+2

Je ne dirais pas que cet exemple de code contourne le vrai problème. Au contraire, il met explicitement en évidence le problème. –

10

Une erreur claire se plaignant d'un pointeur nul est préférable à une violation d'accès qui ne dit pas comment cela s'est passé.

+1

+1 pour attraper un pointeur nul plutôt qu'une violation d'accès * possible *. –

+0

Donc, dites-vous que vous codez tous vos objets de cette façon? –

+0

Il est très difficile pour un dereference de pointeur zéro de ne pas aller boom. Vous ne possédez pas la mémoire là-bas. –

1

Et puis il y a toujours la possibilité que le code ne planterait pas en cours d'exécution avec Self nul. Exemple - s'il n'accède à aucun champ de l'objet propriétaire. Dans ce cas, ce test permettrait d'attraper le problème qui serait autrement non détecté.

Encore, cela pousse la programmation défensive à l'extrême. Je n'ai jamais (OK, presque jamais - seulement quand je chasse des wabbits ... errr ... écrasant des bugs) fais ça.

+0

Même si je l'ai fait - c'est une mauvaise forme d'utiliser une méthode non-classe comme s'il s'agissait d'une méthode de classe. –

1

Apparemment, l'intention originale de cette méthode est qu'elle devienne une méthode abstraite.

3

Ceci est une occasion qui devrait certainement conduire à un crash (c'est-à-dire une exception du système d'exploitation telle que "read from address 0x00000000"). Lancer une exception de langue est simplement redondant (et abuser de EAbstractError ici ne l'améliore pas).

La vérification des paramètres d'entrée valides n'est pas une tâche réalisable dans une langue dangereuse, car vous ne pourrez jamais acquérir de certitude, et donc votre gestion des paramètres invalides ne sera jamais cohérente. (Pourquoi lancez-vous une exception quand un pointeur nul est passé, mais pas pour 0x00000001, qui est tout aussi invalide?). Pour une discussion plus technique de cette question, lisez le blog de Larry Osterman sur why not to check for valid pointers.

Une exception doit être notée: dans Delphi, la méthode Free peut être appelée sur un pointeur nul, ce qui bien sûr nécessite ce type de vérification.

Questions connexes