Modificar uno mismo dentro del método constante mediante un puntero no constante a uno mismo

StackOverflow https://stackoverflow.com//questions/22053806

  •  21-12-2019
  •  | 
  •  

Pregunta

En el siguiente ejemplo const El objeto puede modificarse a sí mismo a través de const método, porque en ese método accede a sí mismo a través de non-const puntero.(mismo programa en ideone)

#include <iostream>

struct Object;

Object * g_pObject;

struct Object
{
    Object():m_a(0){}

    void ModifySelfViaConstMethod() const
    {
        g_pObject->m_a = 37;
    }

    int m_a;
};

int main()
{
    Object o;
    g_pObject = &o;

    const Object & co = o;
    std::cout << co.m_a << "\n";
    co.ModifySelfViaConstMethod();
    std::cout << co.m_a << "\n";

    return 0;
}

No soy muy bueno leyendo el estándar C++, así que pregunto aquí:

¿Qué dice la norma sobre esto?

a)const El método no te garantiza que tu objeto permanezca sin modificar cuando haces cosas como esta.

b) ¿Está bien definido eso y debe compilar?

c) otro?

¿Fue útil?

Solución

¿Qué dice la norma sobre esto?

Dice (parafraseando) que this tiene tipo const Object *, de modo que no pueda modificar miembros directamente o llamar a funciones de miembros no constantes a través de this.No dice nada sobre lo que puede hacer con las variables globales a las que la función pueda tener acceso;solo controla el acceso directo al objeto sobre el que se llama la función.

const El método no te garantiza que tu objeto permanezca sin modificar cuando haces cosas como esta.

No, no es así.Establece la intención de que la función no modifique el objeto y proporciona cierta protección contra romper accidentalmente esa intención.No impide que un programador adecuadamente trastornado utilice const_cast, o (como aquí) acoplamiento incontrolado a través de variables globales para romper la promesa.

¿Está bien definido eso y debe compilarse?

Sí. o no es constante en sí mismo, por lo que no hay nada que le impida tomar un puntero o referencia no constante a él.El const en la función miembro solo restringe el acceso al objeto a través de this, no a objetos arbitrarios a través de otros punteros.

Otros consejos

Cuando declaras un const función, es "por tu propio bien".

En otras palabras, lo declaras. const porque según su diseño inicial, no se supone que cambie ningún objeto con el que será invocado durante el tiempo de ejecución.

Si durante algún punto posterior de la implementación de esta función terminas cambiando el objeto, el compilador te "gritará" diciéndote que está mal.

Por supuesto, el compilador podrá identificar dicho intento, sólo cuando se aplique en this.

En el ejemplo dado, el compilador no puede identificar el problema porque requiere una comparación entre this y g_pObject, y dicha comparación solo puede realizarse durante el tiempo de ejecución.

Cuando un método se declara como const, el compilador garantiza que la instancia a la que apunta el this El puntero no se modifica.Si intenta modificar el this Por ejemplo, el compilador falla.Sin embargo, el compilador no tiene forma de saber que g_pObject y this en realidad están apuntando a la misma instancia.Eso requiere una comparación en tiempo de ejecución, y ningún compilador perderá tiempo realizando comparaciones en tiempo de ejecución de cada puntero utilizado dentro de un const método en la remota posibilidad de que podría coincidir con el this puntero.Entonces, si vas a modificar un Object A través de un puntero externo, tendrá que hacer su propia verificación, por ejemplo:

void ModifySelfViaConstMethod() const
{
    if (g_pObject != this)
        g_pObject->m_a = 37;
}

Constancia en C ++ es un instrumento de seguridad, no de seguridad.

El código donde se honra la constancia, probablemente funcionará como se esperaba, y todos los intentos involuntarios de lanzar constancia serán alertos por el compilador.

En los casos en que "Sé lo que estoy haciendo", se puede encontrar toda la variedad de herramientas, desde el operador de const_cast y la palabra clave GeneracodiCodeGode al estilo Banal C estilo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top