Question

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

  

Le const_cast<>() est utilisé pour ajouter / retirer const (RNS) (ou Etreté volatile) d'une variable.

Cela me rend nerveux. Pourrait l'aide d'un comportement inattendu <=>? Si oui, quoi?

Sinon, quand est-il correct d'utiliser <=>?

Était-ce utile?

La solution

const_cast est sûr que si vous coulée une variable qui était à l'origine non - const. Par exemple, si vous avez une fonction qui prend un paramètre d'un const char *, et vous passez dans un modifiable char *, il est sûr de ce paramètre retour <=> à le modifier et <=>. Toutefois, si la variable d'origine était en fait <=>, puis à l'aide se traduira par <=> un comportement non dé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

Autres conseils

Je peux penser à deux situations où const_cast est sûr et utile (il peut y avoir d'autres cas valides).

L'un est quand vous avez une instance const, référence ou pointeur, et que vous voulez passer un pointeur ou une référence à une API qui n'est pas const correcte, mais que vous êtes certain ne modifiera pas l'objet. Vous pouvez const_cast le pointeur et le transmettre à l'API, en espérant que ce 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 compilateur plus ancien qui n'implémente pas « mutable », et que vous voulez créer une classe qui est logiquement const mais pas const bit. Vous pouvez const_cast « ce » dans une méthode const et modifier des 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];
    }
};

Je trouve difficile de croire que c'est le que informations que vous pourriez trouver sur les const_cast. Je cite Google seconde a frappé :

  

Si vous rejetez la constness d'un   objet qui a été explicitement   déclarée comme const, et tenter de   modifier, le résultat est indéfini.

     

Cependant, si vous rejetez la   constness d'un objet qui n'a pas   été explicitement déclarée comme const, vous   peut le modifier en toute sécurité.

Qu'est-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 au type points this, nous appelons la version const de getT, puis on enlève const du type de retour, ce qui est valable puisque doit être non t-const ( sinon, la version non-const de n'aurait <=> été appelé). Cela peut être très utile si vous avez un grand corps de la fonction et que vous voulez éviter le code redondant.

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

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

Lorsque vous coulée, ce que vous dites en substance est: « Je sais quelque chose que le compilateur ne sait pas. » Dans le cas de const_cast, ce que vous dites est: « Même si cette méthode prend une référence non-const ou pointeur, je sais que cela ne changera pas le paramètre que je le passe. »

Donc, si vous ne savez vraiment pas ce que vous prétendez savoir en utilisant le casting, il est bien de l'utiliser.

Vous détruire toute chance de fil de sécurité, si vous commencez à modifier les choses que le compilateur pensé étaient const.

#include <iostream>
using namespace std;

void f(int* p) {
  cout << *p << endl;
}

int main(void) {
  const int a = 10;
  const int* b = &a;

  // Function f() expects int*, not const int*
  //   f(b);
  int* c = const_cast<int*>(b);
  f(c);

  // Lvalue is const
  //  *b = 20;

  // Undefined behavior
  //  *c = 30;

  int a1 = 40;
  const int* b1 = &a1;
  int* c1 = const_cast<int*>(b1);

  // Integer a1, the object referred to by c1, has
  // not been declared const
  *c1 = 50;

  return 0;
}

source: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fkeyword_const_cast.htm

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