const_cast vs reinterpret_cast

const_cast vs reinterpret_cast

本文关键字:cast reinterpret vs const      更新时间:2023-10-16

参考c++常见问题解答何时应该使用static_cast、dynamic_cast和reinterpret_cast ?

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

我可以合理地理解为什么只使用const_cast将const变量强制转换为非const,但是我不能找出使用reinterpret_cast而不是const_cast来添加constness的合理理由。

我明白使用reinterpret_cast来添加constness是不理智的,但是使用reinterpret_cast来添加constness会是一个UB或潜在的定时炸弹吗?

我在这里感到困惑的原因是因为语句

在很大程度上,使用reinterpret_cast你得到的唯一保证是if您将结果强制转换回原始类型,您将得到精确的相同的值。

如果我用reinterpret_cast添加constness如果你用reinterpret_cast将结果转换回原始类型,它应该返回到原始类型而不应该是UB,但这违反了只能用const_cast删除constness的事实

另外,标准保证你可以使用reinterpret case 来添加Constness。

5.2.10 Reinterpret cast (7) ......当将"指向T1的指针"类型的右值v转换为"指向cv T2的指针"类型时,结果为如果T1和T2都是,则static_cast(static_cast(v)标准布局类型(3.9)及T2的走线要求如下不严格于T1........

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

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

换句话说,如果你要从const char*char*(希望是因为有一个不好的API你不能改变),那么const_cast是你的朋友。这才是真正的目的。

但如果你需要从MyPODType*const char*,你需要reinterpret_cast,这只是很好,不需要const_cast在上面

有一件事要记住:您不能使用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,其中讨论了一种不那么hackish的替代方法。

变成

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

UINT ThreadFunction(void* param)
{
    const MyClass* ptr = reinterpret_cast<const MyClass*>(param);
}

是的,正如你所知道的,const_cast意味着它从特定类型中移除constness。

但是,当我们需要为类型添加constness时。我们一定要这么做吗?

例如

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

reinterpret_cast与'const'无关。

const_cast意味着两件事。第一种方法是从类型中移除constness,另一种方法是赋予其代码显式性。因为你可以使用c风格的强制转换,但这不是显式的,所以不推荐使用。

它们的功能不同。