Eliminazione di un puntatore a const (T const *)

Ho una domanda di base riguardante i puntatori const. Non sono autorizzato a chiamare funzioni membro non const tramite un puntatore const. Tuttavia, sono autorizzato a farlo su un puntatore const:

delete p; 

Questo chiamerà il distruttore della class che in sostanza è un “metodo” non const. Perché è permesso? È solo per supportare questo:

 delete this; 

O c’è qualche altra ragione?

È per supportare:

 // dynamically create object that cannot be changed const Foo * f = new Foo; // use const member functions here // delete it delete f; 

Ma nota che il problema non è limitato agli oggetti creati dynamicmente:

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

Se non è ansible chiamare i distruttori su oggetti const, non è ansible utilizzare affatto gli oggetti const.

Mettilo in questo modo – se non fosse permesso non ci sarebbe modo di cancellare gli oggetti const senza usare const_cast.

Semanticamente, const è un’indicazione che un object dovrebbe essere immutabile. Ciò non implica, tuttavia, che l’object non debba essere cancellato.

Non sono autorizzato a chiamare funzioni membro non const tramite un puntatore const.

Sì, sei tu.

 class Foo { public: void aNonConstMemberFunction(); }; Foo* const aConstPointer = new Foo; aConstPointer->aNonConstMemberFunction(); // legal const Foo* aPointerToConst = new Foo; aPointerToConst->aNonConstMemberFunction(); // illegal 

Hai confuso un puntatore const a un object non const, con un puntatore non-const a un object const.

Avendolo detto,

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

è legale eliminarlo, per i motivi già indicati dalle altre risposte qui.

Costruttori e distruttori non devono essere considerati come “metodi”. Sono costrutti speciali per inizializzare e abbattere un object di una class.

‘puntatore const’ indica che lo stato dell’object non verrà modificato quando le operazioni vengono eseguite su di esso mentre è vivo.

Un altro modo per guardarlo: il significato preciso di un puntatore const è che non sarai in grado di apportare modifiche all’object puntato che sarebbe visibile attraverso questo o qualsiasi altro puntatore o riferimento allo stesso object. Ma quando un object si distrugge, tutti gli altri puntatori all’indirizzo precedentemente occupato dall’object cancellato non sono più puntatori a quell’object . Memorizzano lo stesso indirizzo, ma quell’indirizzo non è più l’indirizzo di alcun object (infatti potrebbe essere presto riutilizzato come indirizzo di un object diverso).

Questa distinzione sarebbe più ovvia se i puntatori in C ++ si comportassero come riferimenti deboli, cioè non appena l’object viene distrutto, tutti i puntatori esistenti su di esso verranno immediatamente impostati su 0 . (Questo è il tipo di cosa considerata troppo costosa in fase di esecuzione per imporre su tutti i programmi C ++, e infatti è imansible renderla completamente affidabile.)

AGGIORNAMENTO : leggendo questo indietro nove anni dopo, è avvocato-ish. Ora trovo comprensibile la tua reazione originale. Disabilitare la mutazione ma permettere la distruzione è chiaramente problematico. Il contratto implicito di puntatori / riferimenti const è che la loro esistenza agirà come un blocco sulla distruzione dell’object target, ovvero la raccolta automatica dei dati inutili.

La solita soluzione a questo è usare quasi ogni altra lingua invece.