web-dev-qa-db-fra.com

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 const à l'aide d'un pointeur const. Cependant, je suis autorisé à le faire sur un pointeur const:

delete p;

Cela appellera le destructeur de la classe qui est essentiellement une "méthode" non-const. Pourquoi est-ce autorisé? Est-ce juste pour soutenir cela:

delete this;

Ou y a-t-il une autre raison?

84
Naveen

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 n'est pas limité aux objets créés dynamiquement:

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

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

106
anon

Autrement dit - si cela n'était pas autorisé, il n'y aurait aucun moyen de supprimer des objets const sans utiliser const_cast.

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

47
PaulJWilliams

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.

'const pointer' est pour indiquer que l'état de l'objet ne sera pas modifié lorsque des opérations seront effectuées sur lui alors qu'il est vivant.

5
Indy9000

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

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 seraient immédiatement définis sur 0. (C'est le genre de chose considéré comme trop coûteux à l'exécution pour s'imposer à tous les programmes C++, et en fait, il est impossible de le rendre entièrement fiable.)

MISE À JOUR : Relire cela neuf ans plus tard, c'est de l'avocat. Je trouve maintenant votre réaction originale compréhensible. Interdire la mutation mais permettre la destruction est clairement problématique. Le contrat implicite des pointeurs/références const est que leur existence agira comme un bloc lors de la destruction de l'objet cible, comme la collecte automatique des ordures.

La solution habituelle est d'utiliser à la place presque n'importe quelle autre langue.

5
Daniel Earwicker

Je ne suis pas autorisé à appeler des fonctions membres non const à l'aide d'un pointeur const.

Oui, 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 avec un objet non const, avec un pointeur non const avec un objet const.

Ayant dit cela,

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

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

5
Oktalist