Vérifier si c'est null
T-il jamais de sens de vérifier si ce est null?
Dire que j'ai une classe avec une méthode; à l'intérieur de cette méthode, je vérifie this == NULL
, et si elle l'est, retourner un code d'erreur.
Si ce est nulle, alors cela signifie que l'objet est supprimé. La méthode est même en mesure de retourner quoi que ce soit?
Mise à jour: j'ai oublié de mentionner que la méthode peut être appelée à partir de plusieurs threads, et il peut causer la suppression de l'objet, tandis qu'un autre thread est à l'intérieur de la méthode.
- Cela ne signifie pas que l'objet a été supprimé. La suppression d'un pointeur n'est pas automatiquement à zéro, et
((Foo*)0)->foo()
est parfaitement valide la syntaxe. Aussi longtemps quefoo()
n'est pas une fonction virtuelle, ce sera même travail sur la plupart des compilateurs, mais c'est juste dégueulasse. - "peut entraîner la suppression de l'objet, tandis qu'un autre thread est à l'intérieur de la méthode". Ce n'est pas acceptable, vous ne devez pas supprimer un objet tout autre code (dans le même thread ou un autre) conserve une référence qu'il utilisera. Il ne sera pas causer des
this
pour devenir nulle dans l'autre thread. - Je suis à la recherche à une situation où ce n'est certainement NULLE. Dieu seul sait pourquoi.
- "cette" semble être null chaque fois que le parent de la classe est abstraite.
- De GCC 6.2 notes de publication: Valeur de la distance de propagation maintenant suppose que le pointeur this de C++ fonctions de membre est non-nulle.
Vous devez vous connecter pour publier un commentaire.
Dans la norme C++, ce n'est pas parce que tout appel à un pointeur null est déjà un comportement indéfini, de sorte que tout le code en s'appuyant sur de tels contrôles est non-standard (il n'y a aucune garantie que le chèque sera même être exécuté).
Noter que ceci est vrai pour les non-virtuel fonctions ainsi.
Certaines implémentations de permis de
this==0
, cependant, et, par conséquent, des bibliothèques écrites spécialement pour les implémentations utilisent parfois comme un hack. Un bon exemple d'une telle paire de VC++ et MFC - je ne me souviens pas le code exact, mais je me souviens distinctement voirif (this == NULL)
vérifie dans le code source MFC quelque part.Il peut aussi être là comme un débogage de l'aide, parce qu'à un certain point dans le passé, le présent code a été frappé avec
this==0
cause d'une erreur de l'appelant, de sorte qu'un chèque a été inséré pour attraper les futurs cas de qui. Une assertion aurait plus de sens pour de telles choses, cependant.Non, cela ne signifie pas que. Cela signifie qu'une méthode a été appelée sur un pointeur null, ou sur une référence obtenue à partir d'un pointeur null (bien que l'obtention d'une telle référence est déjà U. B.). Cela n'a rien à voir avec
delete
, et ne nécessitent pas d'objets de ce type à avoir jamais existé.delete
, le contraire est généralement vrai, si vousdelete
un objet, il n'obtient pas la valeur NULL, et puis vous essayez d'appeler une méthode sur elle, vous verrez quethis != NULL
, mais il sera probablement de crash ou de se comporter de façon étrange, si sa mémoire a déjà été remis en état pour une utilisation par un autre objet.delete
de définir le pointeur à NULL, mais ne l'impose pas, et, dans la pratique, presque pas d'implémentations de le faire.delete
peut pas toujours obtenir une l-value cependant, envisagerdelete this + 0;
Votre remarque à propos des threads est inquiétant. Je suis sûr que vous avez une condition qui peut conduire à un accident. Si un thread supprime un objet et de zéros le pointeur, un autre thread pourrait faire un appel par le pointeur entre ces deux activités, la
this
étant non nulle, et aussi pas valide, résultant dans un accident. De même, si un thread appelle la méthode tandis qu'un autre thread est dans le milieu de la création de l'objet, vous pouvez également obtenir un crash.Réponse courte, vous avez vraiment besoin d'utiliser un mutex ou quelque chose à synchonize accès à cette variable. Vous devez vous assurer que
this
est jamais null ou vous allez avoir des problèmes.operator->
n'est jamais nul 🙂 mais à part cela, je souhaite que je pourrais +10 ce.FWIW, j'ai utilisé le débogage vérifie
(this != NULL)
dans les assertions avant de qui ont aidé à attraper défectueux code. Non pas que le code aurait nécessairement obtenu trop loin avec un crash, mais sur de petits systèmes embarqués qui n'ont pas de protection de la mémoire, les assertions réellement aidé.Sur les systèmes avec protection de la mémoire, l'OS est généralement frappé une violation d'accès si elle est appelée avec une valeur NULL
this
pointeur, il y a donc moins de valeur en affirmantthis != NULL
. Cependant, voir Pavel commentaire pour expliquer pourquoi il n'est pas forcément inutile, même sur les systèmes protégés.this
comme argument.this
sur les systèmes avec protection de la mémoire.this
pointeur si votre programme est en train de faire de mauvaises choses avec l'arithmétique des pointeurs ou peut-être l'appel d'une fonction membre d'une classe d'un objet composé à l'intérieur intégré dans une autre classe par l'intermédiaire d'un pointeur NULL pour le 'extérieure' de la classe. J'espère que cette phrase fait une sorte de sens.Je sais que c'est vieux, mais je sens que maintenant que nous avons affaire avec le C++11-17 quelqu'un doit mentionner les lambdas. Si vous capturez ce dans un lambda qui va être appelée de façon asynchrone à un point plus tard dans le temps, il est possible que votre objet est détruit avant que la lambda est invoquée.
je.e de le transmettre comme un rappel pour un certain temps-cher fonction qui est exécutée à partir d'un thread séparé ou seulement de manière asynchrone en général
EDIT: Juste pour être clair, la question était "est-il toujours un sens pour vérifier si c'est null" j'offre simplement un scénario où il n'a de sens que pourrait devenir plus fréquent avec l'utilisation plus large de C++ moderne.
Exemple artificiel:
Ce code est complètement runable. À voir le comportement à risque simplement en commentaire l'appel à un comportement sécuritaire et décommenter les comportements dangereux appel.
this
pointeur?Votre méthode sera très probablement (peut varier entre compilateurs) être en mesure d'exécuter et aussi être en mesure de retourner une valeur. Tant qu'il n'a pas accès à toutes les variables d'instance. Si elle essaie ce qu'il va se planter.
Que d'autres ont fait remarquer que vous ne pouvez pas utiliser ce test pour voir si un objet a été supprimé. Même si vous pouvez, ça ne marcherait pas, parce que l'objet peut être supprimé par un autre thread, juste après le test, mais avant d'exécuter la ligne suivante après le test. Utiliser la synchronisation des Threads au lieu.
Si
this
est null il y a un bug dans votre programme, le plus probable dans la conception de votre programme.Je sais que c'est une vieille question, mais je pensais que je vais partager mon expérience avec l'utilisation de Lambda capture
Ce segment de code défauts
Si je supprime le
std::cout
déclaration delambda_func
Le code s'exécute à la fin.Semble-t-il cette déclaration
f->lambda_func([f = std::move(f)] () mutable {
processus lambda capture avant que membre de la fonction est appelée.Je voudrais aussi ajouter qu'il est généralement préférable d'éviter (ou null NULL. Je pense que le standard est en train de changer encore une fois ici, mais pour l'instant 0 est vraiment ce que vous voulez vérifier pour être absolument sûr que vous obtenez ce que vous voulez.
C'est juste un pointeur passé comme premier argument à une fonction (ce qui est exactement ce qui en fait une méthode). Tant que vous ne parlez pas de méthodes virtuelles et/ou de l'héritage virtuel, alors oui, vous pouvez trouver vous-même l'exécution d'une méthode d'instance, avec une instance null. Comme les autres ont dit, vous avez presque certainement ne serez pas aller très loin avec cette exécution, avant que les problèmes surviennent, mais robuste, le codage doit probablement la vérification de cette situation, avec une assertion. Au moins, il a un sens quand vous pensez que cela pourrait être présentes pour une raison quelconque, mais de trouver exactement quelle classe /pile d'appel, c'est se produisant dans.