我找不到有关的太多信息const_cast
。我可以找到的唯一信息(堆栈溢出)是:
将
const_cast<>()
用于添加/可变的删除常量(岬)(或挥发性岬)。
这让我感到紧张。可以使用const_cast
导致意外行为的行为吗?如果是这样,该怎么办?
或者,什么时候可以使用const_cast
?
我找不到有关的太多信息const_cast
。我可以找到的唯一信息(堆栈溢出)是:
将
const_cast<>()
用于添加/可变的删除常量(岬)(或挥发性岬)。
这让我感到紧张。可以使用const_cast
导致意外行为的行为吗?如果是这样,该怎么办?
或者,什么时候可以使用const_cast
?
Answers:
const_cast
仅当您强制转换最初不是的变量时才是安全的const
。例如,如果您有一个接受参数a的函数const char *
,并且传入了modifiable char *
,则可以安全地const_cast
将该参数返回给a 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
§7.1.5.1/4 says Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior
任何尝试!没有关于原始变量的文字。
const_cast
删除const
从最初宣称的东西const
。但是实际上尝试写该对象是 UB。只要您阅读就可以了,并且const_cast
本身不会导致UB。这是一个可怕的想法,但它本质上不是UB。
我可以想到const_cast是安全和有用的两种情况(可能还有其他有效情况)。
一种是当您具有const实例,引用或指针,并且想要将指针或引用传递给非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()));
}
另一个是如果您使用的是不实现“可变”功能的较旧的编译器,并且您想创建一个逻辑上为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
会导致不确定的行为,而不是它的有用用途
const_cast
是有效的答案。没有he
问题,因为问题本身就是问题。
我很难相信这是您可以找到的有关const_cast 的唯一信息。引用第二个Google热门歌曲:
如果舍弃已明确声明为const的对象的constness,并尝试对其进行修改,则结果是不确定的。
但是,如果丢弃没有明确声明为const的对象的constness,则可以安全地对其进行修改。
const_cast
。或在其上调用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
,然后调用的const版本getT
,然后从返回类型中删除const,这是有效的,因为它t
必须是非const(否则,非const版本getT
不能被称为)。如果您的函数体很大,并且想要避免多余的代码,这将非常有用。
const_cast
还是static_cast
比较好。const_cast
只能做你想做的:改变简历限定符。static_cast
可以“无声地”执行您不想要的其他操作。但是,第一次强制转换完全是安全的,而且static_cast
往往比更加安全const_cast
。我认为这种情况const_cast
可以更好地传达您的意图,但可以更好地static_cast
传达您的行为安全。
如果您开始修改编译器认为是const的内容,那么您正在破坏线程安全的任何机会。
const
。 const
是信任。const_cast
打破了信任:(
#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
const
通过指定的const
引用/指针修改原始对象时,此问题才变得不安全。相反,如果您只是const_cast
想解决一个糟糕的(或者在我的情况下,是懒惰的)规范的API,该API只接受一个非const
引用,但只会在const
方法中使用……毫无问题。