[英]Is const_cast safe?
我找不到关于const_cast
更多信息。 我能找到的唯一信息(在Stack Overflow上)是:
const_cast<>()
用于添加/删除变量的const(ness)(或volatile-ness)。
这让我很紧张。 使用const_cast
会导致意外行为吗? 如果是这样,什么?
或者,什么时候可以使用const_cast
?
const_cast
只有在您投射最初为非const
的变量时才是安全的。 例如,如果你有一个带有const char *
参数的const char *
,并传入一个可修改的char *
,那么const_cast
将该参数返回char *
并修改它是安全的。 但是,如果原始变量实际上是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实例,引用或指针,并且你想要将指针或引用传递给不是const-correct的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'的旧编译器,并且您希望创建一个逻辑上为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];
}
};
我发现很难相信这是你能找到的关于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添加到this
指向的类型,然后我们调用getT
的const版本,然后我们从返回类型中删除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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.