Yu *_*Hao 10
你是对的,使用const_cast常常表示设计缺陷,或者是你无法控制的API.
但是,有一个例外,它在重载函数的上下文中很有用.我引用了C++ Primer一书中的一个例子:
// return a reference to the shorter of two strings
const string &shorterString(const string &s1, const string &s2)
{
return s1.size() <= s2.size() ? s1 : s2;
}
Run Code Online (Sandbox Code Playgroud)
此函数接受并返回对引用的引用const string.我们可以在一对非const string参数上调用该函数,但我们将获得对a的引用const string作为结果.我们可能希望有一个版本shorterString,当给定非const参数时,将产生一个普通的引用.我们可以使用以下函数编写此函数的版本const_cast:
string &shorterString(string &s1, string &s2)
{
auto &r = shorterString(const_cast<const string&>(s1),
const_cast<const string&>(s2));
return const_cast<string&>(r);
}
Run Code Online (Sandbox Code Playgroud)
此版本shorterString通过将其参数转换为引用来调用const版本const.该函数返回对a的引用const string,我们知道它与我们的原始非const参数绑定.因此,我们知道string&在返回时将该字符串转换回平原是安全的.
const_cast只有在添加const到最初的非const变量时才是安全的.尝试const从原始const对象中删除状态,然后对其执行写入操作将导致未定义的行为.
这个问题是相关的.
另外,msdn页面说(强调我的):
指向任何对象类型的指针或指向数据成员的指针可以显式转换为除const,volatile和__unaligned限定符之外的相同类型.对于指针和引用,结果将引用原始对象.对于指向数据成员的指针,结果将引用与指向数据成员的原始(uncast)指针相同的成员.根据引用对象的类型,通过结果指针,引用或指向数据成员的指针的写入操作可能会产生未定义的行为.您不能使用const_cast运算符直接覆盖常量变量的常量状态.
没有人可以修改你的常量对象const_cast.const_cast不允许修改常量对象.
在删除constness时,目的const_cast是允许从访问路径(指针或引用)中删除导致非常量对象的常量.
例如
int i = 5;
const int *p = &i;
*const_cast<int *>(p) = 10;
assert(i == 10);
Run Code Online (Sandbox Code Playgroud)
在上面的代码const_cast中用于i通过指针获得对对象的修改访问p.对象i本身不是常量,因此修改没有任何问题.
这就是目的const_cast.它也可以用于相反的目的:向指针或引用类型添加 constness.但是"修改常量对象"并不是你可以做的事情const_cast.常量对象不可修改.