提问者:小点点

const_cast vs reinterpret_cast


参考SOC常见问题解答什么时候应该使用static_cast、dynamic_cast和reinterpret_cast?

constcast用于移除或向变量添加const,这是唯一可靠、定义明确且合法的移除const的方法。reinterpretcast用于更改类型的解释。

我以合理的方式理解为什么常量变量应该只使用const_cast转换为非常量变量,但我无法找出使用reinterpret_cast而不是const_cast来增加常量的问题的合理理由。

我明白使用reinterpret_cast来添加constness是不明智的,但使用reinterplet_cast添加constne是一个UB还是潜在的定时炸弹?

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

大体上,使用reinterpret_cast得到的唯一保证是,如果将结果转换回原始类型,则会得到完全相同的值。

因此,如果我使用reinterpret_cast添加恒定性,并且如果您将结果reinterpret_cast回原始类型,则结果应返回原始类型并且不应是UB,但这违反了一个事实,即应该只使用const_cast来删除恒定性

在另一个注释中,标准保证您可以使用reinterpret case添加Constness

5.2.10 重新诠释演员表(7) ...当“指向 T1 的指针”的 prvalue v 转换为“指向 cv T2 的指针”类型时,如果 T1 和 T2 都是标准布局类型 (3.9),并且 T2 的对齐要求不比 T1 的对齐要求严格,则结果为 static_cast(static_cast(v))。。


共3个答案

匿名用户

<code>reinterpret_cast</code>更改对象内数据的解释constcast添加或删除const限定符。数据表示和常数是正交的。因此,有不同的演员关键字是有意义的。

因此,如果我使用reinterpret_cast添加恒定性,并且如果您将结果reinterpret_cast回原始类型,则结果应返回原始类型并且不应是UB,但这违反了一个事实,即应该只使用const_cast来删除恒定性

这甚至无法编译:

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

匿名用户

你不应该只是用reinterpret_cast来添加常量reinterpret_cast应该主要是:重新解释指针(或其他什么)。

换句话说,如果你要从< code>const char*到< code>char*(希望是因为有一个你无法改变的坏API),那么< code>const_cast就是你的朋友。这真的是所有的打算。

但是如果你需要从MyPODType*const char*,你需要reinterpret_cast,它只是不需要一个const_cast在它之上。

匿名用户

有一件事需要记住:不能使用const_cast使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;

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

也就是说,还有几件事:< code>reinterpret_cast是最强大的cast,但也是最危险的一种,所以除非万不得已,否则不要使用它。当您需要从< code>void*转换到< code>sometype*时,请使用< code>static_cast。当走向相反的方向时,也使用内置的隐式转换或使用显式的< code>static_cast。类似地,添加或移除< code>const也是隐式添加的。关于< code>reinterpret_cast,另请参见C语言中的讨论,在讨论不太复杂的替代方案时,我们何时应该更喜欢使用双链式static_cast而不是reinterpret_cast。

乌利