什么是const_cast的合法使用

mac*_*han 10 c++ const

与帮助const_cast,如果有一个人是要修改我的声明常量对象又是什么用的const预选赛?

我的意思是有人如何确保他所宣称的const不会被修改?

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&在返回时将该字符串转换回平原是安全的.

  • @MatthieuM.我认为`const_cast`是适当的工具.使用`static_cast`,您可能会意外更改类型.但这主要是编码风格的问题. (2认同)
  • @Angew:这确实是有争议的,只是任何对 `const_cast` 或 `reinterpret_cast` 的使用都是**潜在危险的**,因此将其用于可能是隐式转换的内容......请注意,如果我们退出单线世界:`auto const&amp; ss1 = s1; ...` 将达到相同的效果,没有虚假的 `const_cast`。 (2认同)

Sin*_*all 7

const_cast只有在添加const到最初的非const变量时才是安全的.尝试const从原始const对象中删除状态,然后对其执行写入操作将导致未定义的行为.

这个问题是相关的.

另外,msdn页面说(强调我的):

指向任何对象类型的指针或指向数据成员的指针可以显式转换为除const,volatile和__unaligned限定符之外的相同类型.对于指针和引用,结果将引用原始对象.对于指向数据成员的指针,结果将引用与指向数据成员的原始(uncast)指针相同的成员.根据引用对象的类型,通过结果指针,引用或指向数据成员的指针的写入操作可能会产生未定义的行为.您不能使用const_cast运算符直接覆盖常量变量的常量状态.


AnT*_*AnT 6

没有人可以修改你的常量对象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.常量对象不可修改.