Modification de soi dans la méthode const via un pointeur non const vers soi

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

  •  21-12-2019
  •  | 
  •  

Question

Dans l'exemple suivant const l'objet peut se modifier via const méthode, car dans cette méthode, il accède à lui-même via non-const aiguille.(même programme sur 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;
}

Je ne suis pas très doué pour lire le standard C++, alors je demande ici :

Que dit la norme à ce sujet ?

un)const la méthode ne vous garantit pas que votre objet reste inchangé lorsque vous faites des choses comme celle-ci

b) Est-ce que c'est bien défini ça et il faut compiler

c) autre ?

Était-ce utile?

La solution

Que dit la norme à ce sujet ?

Il dit (paraphrasant) que this a du type const Object *, de sorte que vous ne puissiez pas modifier directement les membres ou appeler des fonctions membres non const via this.Cela ne dit rien sur ce que vous pouvez faire avec les variables globales auxquelles la fonction pourrait avoir accès ;il contrôle uniquement l'accès direct à l'objet sur lequel la fonction est appelée.

const la méthode ne vous garantit pas que votre objet reste inchangé lorsque vous faites des choses comme celle-ci

Non, ce n'est pas le cas.Il indique l'intention que la fonction ne modifiera pas l'objet et offre une certaine protection contre la rupture accidentelle de cette intention.Cela n'empêche pas un programmeur suffisamment dérangé d'utiliser const_cast, ou (comme ici) un couplage incontrôlé via des variables globales pour rompre la promesse.

Est-ce que c'est bien défini et il faut compiler

Oui. o n'est pas lui-même constant, donc rien ne vous empêche de prendre un pointeur non const ou une référence à celui-ci.Le const sur la fonction membre restreint uniquement l'accès à l'objet via this, pas vers des objets arbitraires via d'autres pointeurs.

Autres conseils

Lorsque vous déclarez un const fonction, c'est "pour votre bien".

En d'autres termes, vous le déclarez const car selon votre conception initiale, il n'est censé modifier aucun objet avec lequel il sera invoqué pendant l'exécution.

Si, à un moment ultérieur de l'implémentation de cette fonction, vous finissez par modifier l'objet, le compilateur vous "criera dessus", vous disant que c'est faux.

Bien entendu, le compilateur sera capable d'identifier une telle tentative, uniquement lorsqu'elle sera appliquée sur this.

Dans l'exemple donné, le compilateur ne peut pas identifier le problème car il nécessite une comparaison entre this et g_pObject, et une telle comparaison ne peut avoir lieu que pendant l'exécution.

Lorsqu'une méthode est déclarée comme const, le compilateur s'assure que l'instance pointée par le this le pointeur n’est pas modifié.Si vous essayez de modifier le this par exemple, le compilateur échoue.Cependant, le compilateur n'a aucun moyen de savoir que g_pObject et this pointent en fait vers la même instance.Cela nécessite une comparaison à l'exécution, et aucun compilateur ne perdra de temps à effectuer des comparaisons à l'exécution de chaque pointeur utilisé dans un const méthode au cas où ils pourrait correspond à this aiguille.Donc, si vous envisagez de modifier un Object via un pointeur externe, vous allez devoir faire votre propre vérification, par exemple :

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

La constance en C++ est un instrument de sécurité, pas de sécurité.

Le code dans lequel la constance est honorée fonctionnera très probablement comme prévu, et toutes les tentatives involontaires de rejet de la constance seront alertées par le compilateur.

Dans les cas où "je sais ce que je fais", on peut trouver toute une variété d'outils, depuis const_cast opérateur et mutable mot-clé du casting banal de style C.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top