Frage

Ich kann nicht viele Informationen über const_cast finden. Die einzige Info I (auf Stack-Überlauf) finden könnte, ist:

  

Die const_cast<>() verwendet const (Ness) (oder flüchtige Heit) einer Variablen hinzuzufügen / zu entfernen.

Das macht mich nervös. Könnte ein const_cast Ursache unerwartetes Verhalten mit? Wenn ja, was?

Wenn alternativ ist es in Ordnung, const_cast zu benutzen?

War es hilfreich?

Lösung

const_cast ist nur sicher, wenn Sie eine Variable sind Gießen, die ursprünglich nicht-const war. Zum Beispiel, wenn Sie eine Funktion, die einen Parameter eines const char * nimmt, und Sie passieren in einem änderbaren char *, dann ist es sicher, dass der Parameter wieder auf einen const_cast und ändern Sie es char *. Wenn jedoch die ursprüngliche Variable in der Tat const ist, dann const_cast mit einem undefinierten Verhalten führen.

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

Andere Tipps

Ich kann von zwei Situationen denken, wo const_cast sicher und nützlich ist (es können auch andere gültige Fälle sein).

Eine davon ist, wenn Sie einen const Beispiel Referenz haben, oder Zeiger, und Sie wollen einen Zeiger oder Verweis auf eine API zu übergeben, die nicht const-korrekt ist, aber dass Sie sicher sind, wird das Objekt nicht ändern. Sie können den Zeiger und übergeben sie an die API const_cast, im Vertrauen, dass es nicht wirklich etwas ändern wird. Zum Beispiel:

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()));
}

Die andere ist, wenn Sie einen älteren Compiler verwenden, die nicht ‚wandelbar‘ nicht implementiert, und Sie wollen, um eine Klasse erstellen, die logisch const ist aber nicht bitweise konst. Sie können ‚dies‘ innerhalb einer const Methode const_cast und Mitglieder Ihrer Klasse ändern.

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];
    }
};

Ich finde es schwer zu glauben, dass das die nur Informationen über const_cast finden kann. Zitiert aus der zweit Google getroffen :

  

Wenn Sie werfen die Konstantheit eines weg   Objekt, das explizit gewesen   erklärt als const, und versuchen,   modifizieren, sind die Ergebnisse nicht definiert.

     

Wenn Sie jedoch die wegzuwerfen   Konstantheit eines Objekts, das nicht der Fall ist   explizit als const deklariert wurde, können Sie   ändern kann es sicher.

Was Adam sagt. Ein weiteres Beispiel, wo const_cast hilfreich sein kann:

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;
};

Wir ersten konst den Typ this Punkte, fügen Sie dann rufen wir die const-Version von getT, und wir dann konst vom Rückgabetyp entfernen, die gültig ist, da t nicht-const (anders sein muss, die nicht-const Version von getT nicht genannt worden sein könnte). Dies kann sehr nützlich sein, wenn Sie eine große Funktion Körper bekam, und Sie möchten redundanten Code vermeiden.

Die kurze Antwort ist nein, es ist nicht sicher.

Die lange Antwort ist, dass, wenn Sie wissen genug, um es zu benutzen, dann sollte es sicher sein.

Wenn Sie werfen, was Sie sagen im Wesentlichen: „Ich weiß etwas, was der Compiler nicht weiß.“ Im Falle von const_cast, was Sie sagen, ist: „Auch wenn diese Methode in einer nicht konstante Referenz oder Zeiger nimmt, ich weiß, dass es ich es passieren den Parameter nicht ändern.“

Wenn Sie also wissen eigentlich, was Sie behaupten, sich mit der Besetzung zu wissen, dann ist es in Ordnung, es zu benutzen.

Sie sind eine Chance auf Thread-Sicherheit zu zerstören, wenn Sie modifizieren die Dinge beginnen, dass der Compiler gedacht waren konst.

#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;
}

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top