因为在任何人的帮助下const_cast
都可以修改我声明的常量对象 -const
限定符有什么用?
我的意思是有人如何确保他声明const
的内容不会被修改?
您是对的,使用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
。我们可以在一对非常量string
参数上调用该函数,但我们会得到一个对 a 的引用const string
作为结果。我们可能希望有一个版本shorterString
,当给定非常量参数时,会产生一个简单的引用。我们可以使用以下函数编写此版本的函数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
。该函数返回对 a 的引用const string
,我们知道它绑定到我们原始的非常量参数之一。因此,我们知道在 return 中将该字符串转换回普通字符串是安全string&
的。
const_cast
仅当您添加const
到最初的非常量变量时才是安全的。试图const
从一个原本为 const 的对象中删除状态,然后对其执行写操作将导致未定义的行为。
这个问题是相关的。
此外,msdn 页面说(强调我的):
指向任何对象类型的指针或指向数据成员的指针可以显式转换为除 const、volatile 和 __unaligned 限定符外相同的类型。对于指针和引用,结果将引用原始对象。对于指向数据成员的指针,结果将引用与指向数据成员的原始(未转换)指针相同的成员。根据被引用对象的类型,通过生成的指针、引用或指向数据成员的指针的写操作可能会产生未定义的行为。您不能使用 const_cast 运算符直接覆盖常量变量的常量状态。
没有人可以修改你的常量对象,不管有const_cast
没有它。const_cast
不允许修改常量对象。
在删除 constness 时, 的目的const_cast
是允许您从导致非常量对象的访问路径(指针或引用)中删除 constness。
例如
int i = 5;
const int *p = &i;
*const_cast<int *>(p) = 10;
assert(i == 10);
在上面的代码const_cast
中,用于i
通过指针获得对对象的修改访问p
。对象i
本身不是常量,因此该修改没有任何问题。
这就是const_cast
. 它也可以用于相反的目的:为指针或引用类型添加常量。但是“修改常量对象”不是你可以用const_cast
. 常量对象是不可修改的。
const_cast
抛弃 const 的一种可能用途是调用不使用const
参数但仍不修改其参数或仅修改其本地副本的 C 函数。
丢弃const
零件然后修改数据肯定会导致未定义的行为。