const_cast是否安全?

我无法find关于const_cast很多信息。 我能find的唯一信息(堆栈溢出)是:

const_cast<>()用于添加/删除variables的const(ness)(或volatile)。

这让我紧张。 可以使用const_cast导致意外的行为? 如果是这样,什么?

或者,什么时候可以使用const_cast

只有在投射一个原来不是const的variables时, const_cast才是安全的。 例如,如果你有一个函数接受一个const char *的参数,并且你传递了一个可修改的char * ,那么把这个参数const_cast返回给一个char *并且修改它是安全的。 但是,如果原始variables实际上是const ,则使用const_cast将导致未定义的行为。

 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 

我可以想到const_cast是安全和有用的两种情况(可能有其他有效的情况)。

一个是当你有一个常量实例,引用或指针,并且你想传递一个指针或者引用到一个不是const正确的API,但是你确实不会修改这个对象的时候。 您可以const_cast指针并将其传递给API,相信它不会真的改变任何东西。 例如:

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

另一种是如果你使用一个不实现'mutable'的较老的编译器,并且你想创build一个逻辑上是const但不是按位const的类。 你可以在const方法中const_cast'this'并修改你的类的成员。

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

我觉得很难相信这是你可以find有关const_cast的唯一信息。 从第二个Google引用来引用:

如果抛弃已被显式声明为const的对象的常量并尝试对其进行修改,则结果是未定义的。

但是,如果抛弃未被显式声明为const的对象的常量,则可以安全地对其进行修改。

亚当说什么 const_cast可以有帮助的另一个例子是:

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

我们首先将const添加到指向的types中,然后调用getT的const版本,然后从返回types中移除const,这是有效的,因为t必须是非const的(否则getT的非const版本不能被称为)。 如果你有一个庞大的函数体,并且你想避免多余的代码,这可能是非常有用的。

简短的答案是否定的,这是不安全的。

长久的答案是,如果你知道足够的使用它,那么它应该是安全的。

当你投射的时候,你实际上说的是“我知道编译器不知道的东西”。 在const_cast的情况下,你所说的是:“即使这个方法需要一个非const引用或指针,我知道它不会改变我传递它的参数。

所以,如果你确实知道你在使用演员时声称知道什么,那么使用它就可以了。

如果你开始修改编译器认为是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; } 

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