89 votes

Const_cast est-il sécurisé?

Je ne trouve pas beaucoup d'informations sur const_cast. La seule information que j'ai pu trouver (sur Stack Overflow) est:

Le const_cast <> () est utilisé pour ajouter / supprimer const (ness) (ou volatile-ness) d'une variable.

Cela me rend nerveux. L'utilisation d'un const_cast pourrait-elle provoquer un comportement inattendu? Si oui quoi?

Sinon, quand est-il possible d'utiliser const_cast?

87voto

Adam Rosenfield Points 176408

const_cast est sûre que si vous êtes à la coulée d'une variable a été à l'origine de la non-const. Par exemple, si vous avez une fonction qui prend un paramètre d'un const char *, et que vous passez dans une modifiables char *, const_cast ce paramètre de retour à un char * et de le modifier. Toutefois, si la variable d'origine était en fait const, puis à l'aide de const_cast entraînera un comportement indéfini.

void func(const char *param, size_t sz, bool modify)
{
    if(modify)
        strncpy(const_cast<char *>(param), sz, "new string");
    printf("param: %s\n", param);
}

...

char buffer[16];
const char *unmodifiable = "string constant";
func(buffer, sizeof(buffer), true);  // OK
func(unmodifiable, strlen(unmodifiable), false); // OK
func(unmodifiable, strlen(unmodifiable), true);  // UNDEFINED BEHAVIOR

34voto

Fred Larson Points 27404

Je pense à deux situations où const_cast est utile (il peut y avoir d'autres cas).

C'est quand vous avez un const exemple, de référence ou pointeur, et que vous souhaitez passer un pointeur ou une référence à une API qui n'est pas const-correct, mais que vous êtes CERTAIN de ne pas modifier l'objet. Vous pouvez const_cast le pointeur et le transmettre à l'API, en espérant qu'il ne sera pas vraiment changer quoi que ce soit. Par exemple:

void log(char* text);   // Won't change text -- just const-incorrect

void my_func(const std::string& message)
{
    log(const_cast<char*>(&message.c_str()));
}

L'autre est si vous utilisez un vieux compilateur de ne pas mettre en oeuvre une "mutables", et vous souhaitez créer une classe qui est logiquement const mais pas au niveau du bit const. Vous pouvez const_cast " il " au sein d'un const méthode et de modifier les membres de votre classe.

class MyClass
{
    char cached_data[10000]; // should be mutable
    bool cache_dirty;        // should also be mutable

  public:

    char getData(int index) const
    {
        if (cache_dirty)
        {
          MyClass* thisptr = const_cast<MyClass*>(this);
          update_cache(thisptr->cached_data);
        }
        return cached_data[index];
    }
};

23voto

Rob Kennedy Points 107381

J'ai du mal à croire que c'est la seule information que vous pourriez trouver sur const_cast. Citant le deuxième Google a frappé:

Si vous avez dédaigné la constness d'un objet qui a été explicitement déclarée const, et de tenter de modifier, les résultats ne sont pas définis.

Toutefois, si vous avez jeté loin de la constness d'un objet qui n'a pas été explicitement déclaré const, vous pouvez la modifier en toute sécurité.

11voto

Ce que dit Adam. Un autre exemple où const_cast peut être utile:

struct sample {
    T& getT() { 
        return const_cast<T&>(static_cast<const sample*>(this)->getT()); 
    }

    const T& getT() const { 
       /* possibly much code here */
       return t; 
    }

    T t;
};

Nous avons d'abord ajouter const pour le type this de points à, puis nous appelons la const version de getT, et puis on enlève const du type de retour, ce qui est valable depuis t doit être non-const (dans le cas contraire, la non-const version de getT ne pouvait pas avoir été appelé). Cela peut être très utile si vous avez un grand corps de la fonction et que vous voulez éviter de code redondant.

9voto

JohnMcG Points 5062

La réponse courte est non, il n'est pas sûr.

La réponse longue est que si vous en savez assez pour l'utiliser, alors il doit être sûr.

Lorsque vous êtes à la coulée, ce que vous êtes essentiellement en disant, "je sais quelque chose que le compilateur ne sait pas." Dans le cas de const_cast, ce que vous dites se, "Même si cette méthode prend en non-const de référence ou un pointeur, je sais que cela ne va pas changer le paramètre-je le laisser passer."

Donc, si vous ne savez vraiment ce que vous réclamez à savoir à l'aide de la fonte, puis c'est bien de l'utiliser.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X