84 votes

Suppression d'un pointeur sur const (T const*)

J'ai une question de base concernant les pointeurs const. Je ne suis pas autorisé à appeler des fonctions membres non constantes à l'aide d'un pointeur constant. Cependant, je suis autorisé à le faire sur un pointeur constant :

delete p;

Cela appellera le destructeur de la classe qui, par essence, est une "méthode" non convertie. Pourquoi cela est-il autorisé ? Est-ce seulement pour soutenir ceci ?

delete this;

Ou y a-t-il une autre raison ?

120voto

C'est pour soutenir :

// dynamically create object that cannot be changed
const Foo * f = new Foo;

// use const member functions here

// delete it
delete f;

Mais notez que le problème ne se limite pas aux objets créés dynamiquement :

{
 const Foo f;
 // use it
} // destructor called here

Si les destructeurs ne pouvaient pas être appelés sur les objets const, nous ne pourrions pas du tout utiliser les objets const.

46voto

PaulJWilliams Points 11641

Disons-le ainsi - si c'est n'étaient pas autorisé, il n'y aurait aucun moyen de supprimer les objets const sans utiliser const_cast.

Sémantiquement, const est une indication qu'un objet doit être immuable. Cela n'implique pas, cependant, que l'objet ne doit pas être supprimé.

5voto

Oktalist Points 31

Je ne suis pas autorisé à appeler des fonctions membres non constantes en utilisant un pointeur constant.

Si, vous l'êtes.

class Foo
{
public:
  void aNonConstMemberFunction();
};

Foo* const aConstPointer = new Foo;
aConstPointer->aNonConstMemberFunction(); // legal

const Foo* aPointerToConst = new Foo;
aPointerToConst->aNonConstMemberFunction(); // illegal

Vous avez confondu un pointeur const vers un objet non const, avec un pointeur non const vers un objet const.

Cela dit,

delete aConstPointer; // legal
delete aPointerToConst; // legal

il est légal de supprimer l'un ou l'autre, pour les raisons déjà énoncées par les autres réponses ici.

5voto

Kip9000 Points 4462

Les constructeurs et les destructeurs ne doivent pas être considérés comme des "méthodes". Ce sont des constructions spéciales pour initialiser et détruire un objet d'une classe.

L'expression "pointeur constant" indique que l'état de l'objet ne sera pas modifié lorsque des opérations sont effectuées sur celui-ci alors qu'il est vivant.

5voto

Daniel Earwicker Points 63298

Une autre façon de voir les choses : la signification précise d'un pointeur constant est que vous ne pourrez pas apporter à l'objet pointé des modifications qui seraient visibles via ce pointeur ou tout autre pointeur ou référence au même objet. Mais lorsqu'un objet est détruit, tous les autres pointeurs vers l'adresse précédemment occupée par l'objet supprimé ne sont plus des pointeurs vers cet objet . Ils stockent la même adresse, mais cette adresse n'est plus l'adresse d'aucun objet (en fait, elle pourrait bientôt être réutilisée comme adresse d'un autre objet).

Cette distinction serait plus évidente si les pointeurs en C++ se comportaient comme des références faibles, c'est-à-dire que dès que l'objet est détruit, tous les pointeurs existants vers lui sont immédiatement mis à la valeur 0 . (C'est le genre de chose considérée comme trop coûteuse à l'exécution pour être imposée à tous les programmes C++, et en fait il est impossible de la rendre entièrement fiable).

UPDATE : En relisant ça neuf ans plus tard, ça fait avocat. Je trouve maintenant votre réaction initiale compréhensible. Interdire la mutation mais autoriser la destruction est clairement problématique. Le contrat implicite des pointeurs/références const est que leur existence agira comme un blocage sur la destruction de l'objet cible, c'est-à-dire la collecte automatique des déchets.

La solution habituelle consiste à utiliser presque n'importe quel autre langage à la place.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X