Pregunta Eliminar un puntero a const (T const *)


Tengo una pregunta básica sobre los indicadores de const. No puedo llamar a ninguna función que no sea const con un puntero const. Sin embargo, se me permite hacer esto en un puntero const:

delete p;

Esto llamará al destructor de la clase que, en esencia, es un "método" no const. ¿Por qué está permitido? ¿Es solo para apoyar esto?

delete this;

¿O hay alguna otra razón?


74
2018-04-16 08:18


origen


Respuestas:


Es para apoyar:

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

// use const member functions here

// delete it
delete f;

Pero tenga en cuenta que el problema no se limita a los objetos creados dinámicamente:

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

Si no se pudiera invocar a los destructores sobre los objetos const, no podríamos usar los objetos const.


92
2018-04-16 08:21



Ponlo de esta manera, si no fueron permitido no habría forma de eliminar objetos const sin usar const_cast.

Semánticamente, const es una indicación de que un objeto debe ser inmutable. Eso no implica, sin embargo, que el objeto no se deba eliminar.


39
2018-04-16 08:22



No puedo llamar a ninguna función que no sea const con un puntero const.

Sí es usted.

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

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

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

Ha confundido un puntero const con un objeto non-const, con un puntero no const a un objeto const.

Una vez dicho esto,

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

es legal eliminar cualquiera, por las razones ya indicadas por las otras respuestas aquí.


6
2017-10-13 18:16



Los constructores y destructores no deben ser vistos como 'métodos'. Son construcciones especiales para inicializar y derribar un objeto de una clase.

'const pointer' es indicar que el estado del objeto no se modificará cuando se realicen operaciones mientras está activo.


5
2018-04-16 08:30



Otra forma de verlo: el significado preciso de un puntero de const es que no podrá realizar cambios en el objeto apuntado que sería visible a través de ese o cualquier otro puntero o referencia al mismo objeto. Pero cuando un objeto se destruye, todos los demás apuntadores a la dirección previamente ocupada por el objeto ahora borrado ya no son punteros a ese objeto. Almacenan la misma dirección, pero esa dirección ya no es la dirección de ningún objeto (de hecho, pronto puede reutilizarse como la dirección de un objeto diferente).

Esta distinción sería más obvia si los punteros en C ++ se comportaran como referencias débiles, es decir, tan pronto como se destruya el objeto, todos los punteros existentes se establecerán inmediatamente en 0. (Ese es el tipo de cosas consideradas demasiado costosas en tiempo de ejecución para imponer en todos los programas C ++, y de hecho es imposible hacerlo completamente confiable.)

ACTUALIZAR: Leyendo esto nueve años después, es abogado. Ahora me parece comprensible tu reacción original. No permitir la mutación pero permitir la destrucción es claramente problemático. El contrato implícito de const punteros / referencias es que su existencia actuará como un bloque en la destrucción del objeto objetivo, a.k.a. la recolección automática de basura.

La solución habitual para esto es usar casi cualquier otro idioma.


5
2018-04-16 13:47