11
votes

C ++ doit supprimer des références?

Dans le code suivant:

~x()
{
  delete m_ref;
}


2 commentaires

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


5 Réponses :


19
votes

NO.

Vous n'avez besoin que de Supprimer 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.


9 commentaires

Comment la langue l'empêche-t-elle?


@Troubadour foo & a; Supprimer A; é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 .


@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 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.



6
votes

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 neuf . 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 dans votre destructeur: xxx

mais en général, il est préférable d'éviter même cela et d'utiliser des pointeurs intelligents à la place. < / p>


2 commentaires

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?



8
votes

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 et il est à la charge de cette classe de nettoyer après cet objet, alors vous appelez Supprimer .

C'est techniquement possible Une référence peut se référer à un objet attribué dynamiquement: xxx

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.


0 commentaires

2
votes

Je veux clarifier certaines idées fausses que vous semblez avoir qui dépasse l'intention de votre question:

Quand un destructeur d'une classe est appelé tous les membres des membres de ses membres sont également appelés.

appeler Supprimer n'est pas le même que d'appeler le destructeur. Supprimer appelle explicitement le destructeur et appelle également Opérateur Supprimer à l'emplacement des objets, c'est une chose de 2 personnes.


3 commentaires

Juste pour clarifier, vous avez mentionné Tous les destructeurs des membres sont appelés aussi bien . 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 ..



1
votes

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.


2 commentaires

"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 .