Dans le code suivant:
~x() { delete m_ref; }
5 Réponses :
NO. P>
Vous n'avez besoin que de Supprimer code> un objet si vous le possédez. Si vous avez été transmis une référence, cela signifie que quelqu'un d'autre le possède, il est donc inutile et heureusement, la langue l'empêche. P>
Comment la langue l'empêche-t-elle?
@Troubadour foo & a; Supprimer A; CODE> échouera (sauf lorsque FOO est un type de pointeur).
@Ttroubadour: Comme le mentionnait l'OP, cela ne compile tout simplement pas.
@TStenner, @Matthieu m.: Ce n'est pas la même chose que la "langue l'empêche". Juste faire foo & a; Supprimer et a code>.
@Troubadour: Ah mais ici, vous supprimez un pointeur. La façon dont vous avez obtenu le pointeur n'a pas d'importance dans la langue (c'est C ++), mais vous deviez faire extrawork pour l'obtenir et, espérons-le, vous avez réalisé que vous le faisiez mal.
@Matthieu m.: Êtes-vous d'accord pour dire que la langue ne l'empêche pas?
@Ttroubadour: Nous ne parlons pas de la même chose :) La langue empêche la suppression d'une référence aléatoire, mais vous permettez d'appeler Supprimer code> sur n'importe quel pointeur. Je suis donc en désaccord avec vous sur ce point, mais d'accord avec vous sur le point général que la langue n'empêche pas grand chose.
@Matthieu M.: Pour débutant La deuxième phrase de votre réponse implique deux choses. Tout d'abord, la transmission d'une référence garantit que la propriété repose ailleurs et d'autre part que la langue vous empêche de supprimer un objet si tout ce que vous avez est une référence. Ces deux ne sont pas vraies. Je sais exactement ce que vous voulez dire, je ne pense pas que c'est assez clair pour un débutant.
@Troubadour: ah! Désolé, je ne parlais certainement pas avec un état d'esprit débutant. J'ai peur que C ++ soit très méchant pour les débutants ... Il y a juste trop de pièges lorsqu'il s'agit de faire l'objet de la vie que les autres langues n'exposent plus.
Non. Vous ne pouvez supprimer que des pointeurs, non des références, et même alors vous devez uniquement supprimer des objets que vous avez alloués à l'aide de l'opérateur mais en général, il est préférable d'éviter même cela et d'utiliser des pointeurs intelligents à la place. < / p> p> neuf code>. Et puis vous devez être sûr de les supprimer qu'une seule fois. Voici le cas dans lequel vous auriez besoin d'utiliser
Supprimer code> dans votre destructeur:
Juste pour clarifier, si le destructeur du parent est appelé, cela appellera-t-il également les destructeurs des membres qui ont été adoptés par référence? Je suppose que ce ne sera pas parce que cela n'a pas été initialisé par la classe mais je pourrais me tromper.
Comment est-ce lié aux variables de référence?
Je ne pense pas que l'un en réalité parle strictement supprime même les pointeurs. Ce que vous supprimez sont des objets alloués de manière dynamique (ou des tableaux d'objets) que le pointeur est une poignée pour. Si l'objet provient d'un appel à nouveau strud> et il est à la charge de cette classe de nettoyer après cet objet, alors vous appelez Supprimer strud>. C'est techniquement possible Une référence peut se référer à un objet attribué dynamiquement: p> Cependant, ce serait un style incroyablement mauvais. Par convention, la poignée "possédant" d'un objet alloué de manière dynamique ne doit pas être une référence. P> p>
Je veux clarifier certaines idées fausses que vous semblez avoir qui dépasse l'intention de votre question: P>
Quand un destructeur d'une classe est appelé tous les membres des membres de ses membres sont également appelés. P>
appeler Supprimer code> n'est pas le même que d'appeler le destructeur.
Supprimer CODE> appelle explicitement le destructeur et appelle également
Opérateur Supprimer CODE> à l'emplacement des objets, c'est une chose de 2 personnes. P>
Juste pour clarifier, vous avez mentionné Tous les destructeurs des membres sont appelés aussi bien code>. Cela inclut-il des membres qui ont été adoptés par référence dans le constructeur? Je suppose que ce n'est pas parce que ces objets ne sont pas appartenant à la classe et ne possédaient probablement probablement l'appelant du constructeur.
@Mel Il y a probablement une citation standard applicable ici que les références sont traitées comme des primitives et n'ont pas de destructeurs. Dans tous les cas, votre hypothèse est correcte.
Désolé, mais cette réponse introduit plus de confusion que des éclaircissements. Envisagez d'ajouter des informations, quelle est la différence entre appeler Suppr et Objets D-tor. En outre, une information cardinale est qu'un objet si un objet détient une référence à quelque chose de plus grand que des types anciens simples (par exemple court), cela devrait signifier que quelqu'un d'autre est responsable de la suppression de cet objet - le véritable propriétaire ..
Pour un petit peu de clarification supplémentaire, je souhaite offrir ce qui suit:
int *pi = new int; //int& ir = pi; // can't do // this a reference to the pointer but it is an error // because or the type difference int& vs int* and // static_cast won't help. reinterpret_cast would allow // the assignment to take place but not help the 'delete ir' int& ir = *pi; // this is OK - a reference to what the pointer points to. // In other words, the the address of the int on the heap. //delete ir; // can't do, it is a reference and you can't delete non-pointers. delete &ir; // this works but it is still not "deleting a reference". // The reference 'ir' is another name for the heap-based int. // So, &ir is the address of that int, essentially a pointer. // It is a pointer that is being used by delete, not a reference.
"L'adresse de l'int sur le tas">. <
En fait, à proprement parler, vous ne «supprimerez jamais un pointeur». Vous supprimez des objets alloués de manière dynamique en transmettant des pointeurs à Supprimer code>.
ce morceau de code ne compilera même pas
En cas de doute, jetez un coup d'œil sur Shared_PTR [1], cela s'occupera de toutes vos références et de tous vos indications pour vous. [1] boost.org/doc/libs/1_43_0/libs /smart_ptr/shared_ptr.htm