8

参考 SO C++ FAQ什么时候应该使用 static_cast、dynamic_cast 和 reinterpret_cast?.

const_cast 用于将 const 删除或添加到变量中,它是删除 const 的唯一可靠、已定义且合法的方法。reinterpret_cast 用于更改类型的解释。

我以合理的方式理解为什么 const 变量应该仅使用 const_cast 强制转换为非 const,但我无法找出使用 reinterpret_cast 而不是 const_cast 来添加 const 的合理理由。

我知道使用 reinterpret_cast 甚至添加 constness 是不理智的,但是使用 reinterpret_cast 添加 constness 会是 UB 还是潜在的定时炸弹?

我在这里感到困惑的原因是因为声明

很大程度上,您使用 reinterpret_cast 获得的唯一保证是,如果您将结果转换回原始类型,您将获得完全相同的值。

因此,如果我使用 reinterpret_cast 添加 constness 并且如果您将结果 reinterpret_cast 重新转换为原始类型,它应该返回原始类型并且不应该是 UB,但这违反了一个事实,即应该只使用 const_cast 来删除 constness

在单独的说明中,该标准保证您可以使用重新解释案例添加 Constness

5.2.10 Reinterpret cast (7) ......当“pointer to T1”类型的prvalue v转换为“pointer to cv T2”类型时,如果两个T1都为static_cast(static_cast(v))和 T2 是标准布局类型(3.9),T2 的对齐要求不比 T1 严格......

4

5 回答 5

14

reinterpret_cast改变对象内数据的解释。const_cast添加或删除const限定符。数据表示和常数是正交的。所以有不同的演员关键字是有意义的。

因此,如果我使用 reinterpret_cast 添加 constness 并且如果您将结果 reinterpret_cast 重新转换为原始类型,它应该返回原始类型并且不应该是 UB,但这违反了一个事实,即应该只使用 const_cast 来删除 constness

那甚至不会编译:

int * n = new int;
const * const_added = reinterpret_cast<const int *>(n);
int * original_type = reinterpret_cast<int*>(const_added);
    // error: reinterpret_cast from type ‘const int*’ to type ‘int*’ casts away qualifiers
于 2013-01-11T06:16:11.700 回答
6

你不应该只是添加constwith reinterpret_cast。Areinterpret_cast应该主要是:重新解释指针(或其他)。

换句话说,如果你要从const char*to char*(希望因为有一个糟糕的 API 你不能改变),那么const_cast你就是朋友。这就是它的全部意图。

但是,如果您需要 from MyPODType*to const char*,则需要reinterpret_cast,而且不需要 aconst_cast就很好了。

于 2013-01-11T06:16:52.250 回答
1

需要记住一件事:您不能使用const_cast来使const变量可写。如果 const 引用引用非 const 对象,则只能使用它从 const 引用中检索非 const 引用。听起来很复杂?例子:

// valid:
int x;
int const& x1 = x;
const_cast<int&>(x1) = 0;
// invalid:
int const y = 42;
int const& y1 = y;
const_cast<int&>(y1) = 0;

实际上,这两种方法都可以编译,有时甚至可以“工作”。但是,第二个会导致未定义的行为,并且在许多情况下会在将常量对象放置在只读内存中时终止程序。

也就是说,还有几件事:reinterpret_cast是最强大的演员,但也是最危险的演员,所以除非必须,否则不要使用它。当您需要从void*到 时sometype*,请使用static_cast. 反方向时,使用内置的隐式转换或使用显式转换static_cast。与添加或删除类似const,这也是隐式添加的。关于reinterpret_cast,另请参见C++ 的讨论 何时我们应该更喜欢使用两个链接的 static_cast 而不是 reinterpret_cast,其中讨论了一种不那么骇人听闻的替代方案。

乌里

于 2013-01-11T06:48:56.137 回答
0

我能想到的将 reinterpret_cast 与 const-ness 联系起来的唯一地方是将 const 对象传递给接受 void 指针的 API -

UINT ThreadFunction(void* param)
{
    const MyClass* ptr = reinterpret_cast<const MyClass*>(param);
}
于 2013-01-11T06:32:03.393 回答
0

是的,如您所知, const_cast 意味着它从特定类型中删除了常量。

但是,当我们需要为类型添加常量时。我们有理由这样做吗?

例如,

void PrintAnything(void* pData)
{
    const CObject* pObject = reinterpret_cast<CObject*>(pData);
    // below is bla-bla-bla.
}

reinterpret_cast 与 'const' 无关。

const_cast 意味着两件事。第一个是从类型中删除常量,另一个是赋予其代码明确性。因为您可以使用 C-style cast 来使用它,但这不是明确的,因此不推荐。

它们的功能不同。这绝对是不同的。

于 2013-01-11T06:57:36.603 回答