14

因为在任何人的帮助下const_cast都可以修改我声明的常量对象 -const限定符有什么用?

我的意思是有人如何确保他声明const的内容不会被修改?

4

4 回答 4

12

您是对的,使用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&的。

于 2013-09-17T05:42:39.560 回答
7

const_cast仅当您添加const到最初的非常量变量时​​才是安全的。试图const从一个原本为 const 的对象中删除状态,然后对其执行写操作将导致未定义的行为。

这个问题是相关的。

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

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

于 2013-09-17T05:37:34.883 回答
6

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

于 2013-09-17T06:22:27.820 回答
2

const_cast抛弃 const 的一种可能用途是调用不使用const参数但仍不修改其参数或仅修改其本地副本的 C 函数。

丢弃const零件然后修改数据肯定会导致未定义的行为。

于 2013-09-17T05:37:27.993 回答