Est de supprimer ce possible?
Est-il permis de delete this;
si la suppression de l'instruction est la dernière instruction qui sera exécutée sur l'instance de la classe? Bien sûr, je suis sûr que l'objet représenté par la this
-pointeur est new
ly-créé.
Je suis en train de réfléchir à quelque chose comme ceci:
void SomeModule::doStuff()
{
//in the controller, "this" object of SomeModule is the "current module"
//now, if I want to switch over to a new Module, eg:
controller->setWorkingModule(new OtherModule());
//since the new "OtherModule" object will take the lead,
//I want to get rid of this "SomeModule" object:
delete this;
}
Puis-je faire cela?
Principal problème serait que si vous
delete this
vous avez créé un couplage étroit entre la classe et de la méthode de répartition utilisée pour créer des objets de cette classe. Qui est de mauvaise OO conception, puisque la chose la plus fondamentale en programmation orientée objet est de rendre autonome les classes qui ne savent pas ou se soucient de ce que leur interlocuteur est en train de faire. Ainsi, un plan bien conçu classe ne sais pas ou se soucient comment il a été affecté. Si vous pour une raison quelconque besoin d'un tel mécanisme particulier, je pense qu'un meilleur design serait d'utiliser une classe wrapper autour de la classe réelle, et de laisser le wrapper traitent de la répartition.
OriginalL'auteur Martijn Courteaux | 2010-06-30
Vous devez vous connecter pour publier un commentaire.
Le C++ FAQ Lite dispose d'une entrée spécifiquement pour cette
Je pense que cette citation résume bien
Pour plus de sécurité, vous pouvez utiliser privée destructeur sur l'objet d'origine pour s'assurer de son pas construit sur la pile ou comme une partie d'une matrice ou un vecteur.
Définir 'prudent'
'Attention" est défini dans la FAQ de l'article. (Alors que la FQA lien surtout des coups de gueule - comme presque tout dans il - comment le mauvais C++ est)
OriginalL'auteur JaredPar
Oui,
delete this;
a défini les résultats, aussi longtemps que (comme vous l'avez remarqué) vous assurer que l'objet a été alloué dynamiquement, et (bien sûr) ne tentez jamais d'utiliser l'objet après qu'il soit détruit. Au fil des ans, de nombreuses questions ont été posées à propos de ce que dit la norme spécifiquement surdelete this;
, par opposition à la suppression de certains autres pointeur. La réponse est assez court et simple: il ne veut pas dire grand-chose. Il dit seulement quedelete
'opérande doit être une expression qui désigne un pointeur vers un objet ou un tableau d'objets. Il va dans un peu de détail sur des choses comme la façon dont il calcule ce que (le cas échéant) la fonction de libération pour appeler à la libération de la mémoire, mais la totalité de l'article surdelete
(§[expr.supprimer]) ne mentionne pasdelete this;
spécifiquement à tous. La section sur les destrucors ne mentionnedelete this
en un seul lieu (§[classe.dtor]/13):Qui tend à soutenir l'idée que la norme considère
delete this;
pour être valide, si elle n'était pas valide, son type ne serait pas significative. C'est le seul endroit de la norme mentionnedelete this;
à tous, pour autant que je sais.De toute façon, certains considèrent
delete this
un vilain hack, et de dire à quelqu'un qui vous écoute et qu'il devrait être évitée. On cite souvent des problème est la difficulté de veiller à ce que les objets de la classe ne sont jamais alloué dynamiquement. D'autres considèrent qu'il est parfaitement raisonnable de l'idiome, et de l'utiliser tout le temps. Personnellement, je suis quelque part au milieu: j'ai rarement l'utiliser, mais n'hésitez pas à le faire quand il semble être le bon outil pour le travail.La principale utilisation de cette technique est un objet qui a une durée de vie qui est presque entièrement son propre. Un exemple James Kanze a cité l'une de facturation/système de suivi, il a travaillé pour une compagnie de téléphone. Quand commencer à vous faire un appel téléphonique, quelque chose prend note et crée un
phone_call
objet. À partir de ce moment, lephone_call
objet gère les détails de l'appel (d'une connexion lorsque vous composez, l'ajout d'une entrée dans la base de données-à-dire lorsque l'appel a commencé, éventuellement raccorder plus de gens, si vous effectuez un appel de conférence, etc.) Lorsque les dernières personnes à l'appel, raccrochez, lephone_call
objet est sa dernière tenue de la comptabilité (par exemple, ajoute une entrée à la base de données-à-dire lorsque vous avez raccroché, de sorte qu'ils peuvent calculer combien de temps votre appel), puis détruit lui-même. La durée de vie de laphone_call
objet est basée sur le moment où la première personne commence à l'appeler et quand le dernier des gens quittent l'appel--du point de vue du reste du système, en gros, c'est totalement arbitraire, de sorte que vous ne peut pas attacher à une portée lexicale dans le code, ou quoi que ce soit sur cet ordre.Pour quelqu'un qui pourrait se soucient de fiabilité de ce type de codage peut être: si vous faites un appel téléphonique à, partir de, ou à travers presque toutes les parties de l'Europe, il y a une très bonne chance que c'est d'être manipulé (au moins en partie) par le code qui fait exactement cela.
Vous le ferais probablement que, dans la plupart des cas, de toute façon-je ne sais pas n'importe où près de tous les détails du système qu'il travaillait sur, donc je ne peux pas dire à coup sûr à ce sujet.
La façon dont je reçois souvent de contourner le problème de la façon dont la mémoire a été allouée est d'inclure une
bool selfDelete
paramètre dans le constructeur qui sera affectée à une variable membre. Accordée, ce qui signifie que la remise de la programmeur assez de corde pour attacher la corde au cou, mais je trouve cela préférable à des fuites de mémoire.J'ai fait la même chose, mais je préfère éviter ce qui me semble être une bidouille.
Pour quelqu'un qui peut-être ... il y a une très bonne chance que c'est d'être manipulé (au moins en partie) par le code qui fait exactement
this
. Oui, le code est géré par le exactementthis
. 😉OriginalL'auteur Jerry Coffin
Si cela vous fait peur, il est parfaitement légal hack:
Je pense que
delete this
est idiomatiques C++, et j'seulement à le présenter comme une curiosité.Il y a un cas où cette construction est en fait utile - vous pouvez supprimer l'objet après la levée d'une exception qui a besoin de données membres de l'objet. L'objet reste valide jusqu'à ce que après le lancer.
Remarque: si vous utilisez un compilateur âgés de plus de C++11, vous pouvez utiliser
std::auto_ptr
au lieu destd::unique_ptr
, il fera la même chose.pas sûr de ce que tu veux dire, ça fonctionne pour moi: ideone.com/aavQUK. La création d'un
unique_ptr
de l'autreunique_ptr
nécessite un déplacement, mais pas à partir d'un pointeur brut. Sauf si les choses ont changé en C++17?Ahh C++14, ça va être pourquoi. J'ai besoin de mettre à jour mon c++ sur ma boîte de dev. Je vais essayer de nouveau ce soir sur mon émergé récemment système gentoo!
OriginalL'auteur Mark Ransom
L'une des raisons que le C++ a été conçu a été de le rendre facile à réutiliser le code. En général, C++ doit être écrit afin qu'il fonctionne si la classe est instanciée sur le tas, dans un tableau, ou sur la pile. "Supprimer ce" est une très mauvaise pratique de codage, car il ne fonctionnera que si une seule instance est définie sur le tas; et il vaut mieux ne pas être une autre instruction delete, qui est généralement utilisé par la plupart des développeurs de nettoyer le tas. En faisant cela suppose également qu'aucune maintenance n'programmeur dans le futur, à guérir un mal perçu fuite de mémoire en ajoutant une instruction delete.
Même si vous savez à l'avance que votre plan actuel est de n'attribuer à une instance unique sur le tas, que si quelques happy-go-lucky développeur vient à l'avenir et décide de créer une instance sur la pile? Ou, si il coupe et colle à certaines parties de la classe à une nouvelle classe qu'il a l'intention d'utiliser sur la pile? Lorsque le code atteint "supprimer ce" il vont le supprimer, mais ensuite, lorsque l'objet est hors de portée, il va appeler le destructeur. Le destructeur va alors essayer de le supprimer à nouveau et vous êtes ensuite arrosé. Dans le passé, de faire quelque chose comme ce serait gâcher non seulement le programme, mais le système d'exploitation et l'ordinateur devra être redémarré. En tout cas, ce n'est PAS fortement recommandé et devrait presque toujours être évitée. Je dois être désespéré, au sérieux de plâtre, ou vraiment la haine de la société, j'ai travaillé pour l'écriture du code qui fait cela.
Joh - merci pour le upvote! Je ne comprends pas non plus...
Vous pourriez juste envelopper l'objet que vous souhaitez supprimer lui-même dans une classe spéciale qui supprime l'objet, puis lui-même, et l'utilisation de cette technique pour la prévention de l'allocation de pile: stackoverflow.com/questions/124880/... Il ya des moments où il n'y a vraiment pas une solution viable. J'ai simplement utilisé cette technique pour l'auto-suppression d'un fil qui est commencé par une fonction DLL, mais la fonction de DLL doit revenir avant que le thread se termine.
OriginalL'auteur Bob Bryan
Il est permis (il suffit de ne pas utiliser l'objet qui suivent), mais je ne voudrais pas écrire un tel code sur la pratique. Je pense que
delete this
ne devrait figurer que dans les fonctions qui a appelérelease
ouRelease
et ressemble:void release() { ref--; if (ref<1) delete this; }
.OriginalL'auteur Kirill V. Lyadvinsky
Ainsi, dans le Modèle d'Objet Composant (COM)
delete this
de construction peut être une partie deRelease
méthode qui est appelée à chaque fois que vous souhaitez libérer aquisited objet:OriginalL'auteur UnknownGosu
Vous pouvez le faire. Cependant, vous ne pouvez pas attribuer à ce. Donc la raison de votre état pour ce faire, "je veux changer de vue," semble très discutable. La meilleure méthode, à mon avis, serait de l'objet qui contient le point de vue de remplacer ce point de vue.
Bien sûr, vous êtes à l'aide de RAII les objets et donc vous n'avez pas réellement besoin d'appeler le supprimer à tout...droit?
OriginalL'auteur Crazy Eddie
C'est le cœur de l'idiome de référence-objets comptés.
De comptage de références est une forme forte d'déterministe de la collecte des ordures ménagères - il assure des objets de gérer leur PROPRE vie au lieu de s'appuyer sur les "intelligents" les pointeurs, etc. de le faire pour eux. L'objet sous-jacent n'est jamais accessible par l'intermédiaire "Référence" pointeurs intelligents, conçus de sorte que les pointeurs d'incrémentation et de décrémentation d'un membre entier (le nombre de références) dans l'objet réel.
Lorsque la dernière référence de baisse de la pile ou est supprimé, le nombre de références sera à zéro. Votre objet est le comportement par défaut sera alors un appel à "supprimer ce" garbage collect - les bibliothèques-je écrire fournir un virtuel protégé "CountIsZero" appel de la classe de base de sorte que vous pouvez remplacer ce comportement pour des choses comme la mise en cache.
La clé pour faire de ce coffre n'est pas en permettant aux utilisateurs d'accéder au CONSTRUCTEUR de l'objet en question (il est protégé), mais plutôt de les rendre appeler un membre statique - l'USINE - comme la "Référence statique CreateT(...)". De cette façon, vous SAVEZ qu'ils sont toujours construits avec des "nouvelles" et qu'aucun pointeur brut est toujours disponible, afin de "supprimer ce" ne sera plus jamais le coup.
Vous pouvez aussi simplement faire le destructeur protégé d'interdire la statique et de la pile des allocations de votre objet.
OriginalL'auteur Zack Yezek
C'est un vieux, réponse, question, mais @Alexandre lui demanda: "Pourquoi quelqu'un voudrait-il faire cela?", et j'ai pensé que je pourrait fournir un exemple de l'utilisation que j'envisage cet après-midi.
Du code Legacy. Utilise des pointeurs nus Obj*obj avec une suppression obj à la fin.
Malheureusement, j'ai besoin parfois, pas souvent, pour garder l'objet en vie plus longtemps.
J'envisage d'en faire une référence compté pointeur intelligent. Mais il n'y aurait beaucoup de code à modifier, si j'étais à utiliser
ref_cnt_ptr<Obj>
partout. Et si vous mélangez nu Obj* et ref_cnt_ptr, vous pouvez obtenir l'objet implicitement supprimé lors de la dernière ref_cnt_ptr s'en va, même si il y a des Obj* encore en vie.Donc, je suis en réflexion sur la création d'un explicit_delete_ref_cnt_ptr. I. e. une référence compté pointeur à l'endroit où la suppression est seulement explicite supprimer la routine. Utiliser dans un endroit où le code existant sait la durée de vie de l'objet, ainsi que dans mon nouveau code qui maintient l'objet en vie plus longtemps.
Incrémentation et de décrémentation de la valeur de référence comme explicit_delete_ref_cnt_ptr obtenir manipulés.
Mais ne dispensant PAS lorsque le compteur de référence est vu à zéro explicit_delete_ref_cnt_ptr destructeur.
Seulement de libérer lorsque le compteur de référence est vu à zéro explicite supprimer-comme l'opération. E. g. dans quelque chose comme:
OK, quelque chose comme ça. C'est un peu inhabituel d'avoir une référence compté type de pointeur pas automatiquement la suppression de l'objet pointé dans le rc ed ptr destructeur. Mais il semble que cela pourrait faire de mélange nu pointeurs et rc ed pointeurs un peu plus sûr.
Mais jusqu'à présent, aucun besoin de les supprimer.
Mais alors il me vint: si l'objet pointé, le pointee, sait qu'il est en train de référence compté, par exemple, si le compte est à l'intérieur de l'objet (ou d'une autre table), puis la routine delete_if_rc0 pourrait être une méthode de la pointee objet, pas l' (smart) pointeur.
En fait, il n'a pas besoin d'être un membre de la méthode à tous, mais peut être une fonction libre:
(BTW, je sais que le code n'est pas tout à fait le droit - il devient de moins en moins lisible si j'ajoute tous les détails, donc je laisse comme ça.)
OriginalL'auteur Krazy Glew
Supprimer ce qui est légal, tant que l'objet est dans le tas.
Vous devez exiger de l'objet à tas.
La seule façon de le faire est de rendre le destructeur protégé de cette façon, supprimer peut être appelée UNIQUEMENT à partir de la classe , de sorte que vous besoin d'une méthode qui permettrait de s'assurer de la suppression
OriginalL'auteur Swift - Friday Pie