如同const_cast
的帮助,如果有人要修改我声明的常量对象,那么const
限定符的使用是什么?
我的意思是指某人如何确保他声称为const
的内容不会被修改?
答案 0 :(得分: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;
}
此函数接受并返回对const string
的引用。我们可以在一对非const string
参数上调用该函数,但我们将获得对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);
}
此版本通过将其参数转换为对shorterString
的引用来调用const
的const版本。该函数返回对const string
的引用,我们就是这样
知道是我们原始的非const论证之一。因此,我们知道在返回时将该字符串强制转换回普通string&
是安全的。
答案 1 :(得分:7)
const_cast
添加到最初的非const变量, const
是唯一安全的。尝试从原始const对象中删除const
状态,然后对其执行写入操作将导致未定义的行为。
This question是相关的。
此外,msdn页面说(强调我的):
指向任何对象类型的指针或指向数据成员的指针可以显式转换为除const,volatile和__unaligned限定符之外的相同类型。对于指针和引用,结果将引用原始对象。对于指向数据成员的指针,结果将引用与指向数据成员的原始(uncast)指针相同的成员。 根据引用对象的类型,通过生成的指针,引用或指向数据成员的指针的写入操作可能会产生未定义的行为。 您不能使用const_cast运算符直接覆盖常量变量的常量状态。
答案 2 :(得分:5)
没有人可以使用const_cast
或不使用const_cast
来修改常量对象。 const_cast
不允许修改常量对象。
在删除constness时,int i = 5;
const int *p = &i;
*const_cast<int *>(p) = 10;
assert(i == 10);
的目的是允许您从访问路径(指针或引用)中删除导致非的 -constant对象。
例如
const_cast
在上面的代码中,i
用于通过指针p
修改对对象i
的访问权限。对象const_cast
本身并不是常量,因此修改没有任何问题。
这就是const_cast
的目的。它也可以用于相反的目的:将 constness添加到指针或引用类型。但是“修改常量对象”不是{{1}}所能做到的。常量对象不可修改。
答案 3 :(得分:2)
const_cast
抛弃constness的一个可能用途是调用不使用const
参数的C函数,但仍然不修改它们的参数,或者只修改它们的本地副本。 / p>
抛弃const
部分,然后修改数据肯定会导致未定义的行为。