const_cast vs reinterpret_cast 参考SO C++ FAQ。< /P>

const_cast vs reinterpret_cast 参考SO C++ FAQ。< /P>,c++,casting,constants,reinterpret-cast,C++,Casting,Constants,Reinterpret Cast,const_cast用于删除变量中的const或将其添加到变量中,这是唯一可靠、定义和合法的删除constness的方法。 reinterpret_cast用于更改类型的解释 我以一种合理的方式理解了为什么一个常量变量应该仅使用const_cast转换为非常量,但我无法找到使用reinterpret_cast而不是const_cast来添加常量的问题的合理理由 我知道使用reinterpret_cast来添加常量是不明智的,但使用reinterpret_cast来添加常量会是UB还是潜在的定时炸

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

我以一种合理的方式理解了为什么一个常量变量应该仅使用const_cast转换为非常量,但我无法找到使用reinterpret_cast而不是const_cast来添加常量的问题的合理理由

我知道使用reinterpret_cast来添加常量是不明智的,但使用reinterpret_cast来添加常量会是UB还是潜在的定时炸弹

我之所以在这里感到困惑是因为这句话

在很大程度上,你能从reinterpret_cast中得到的唯一保证是 您将结果强制转换回原始类型,您将获得准确的 相同的值

因此,如果我使用reinterpret_cast添加constness,并且如果您将结果重新解释_cast回原始类型,它应该返回原始类型,并且不应该是UB,但这违反了只应使用const_cast删除constness的事实

另一方面,该标准保证可以使用reinterpret case添加Constness

5.2.10重新解释转换(7)…当“指向T1的指针”类型的PRV值转换为“指向cv T2的指针”类型时,结果为 如果T1和T2都是 T2的标准布局类型(3.9)和对齐要求如下: 不比T1更严格


重新解释\u cast
更改对象内数据的解释
const_cast
添加或删除
const
限定符。数据表示和常量是正交的。因此,使用不同的cast关键字是有意义的

因此,如果我使用reinterpret_cast添加constness,并且如果您将结果重新解释_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
int*n=新的int;
const*const_added=reinterpret_cast(n);
int*原始类型=重新解释转换(增加常数);
//错误:将类型“const int*”转换为类型“int*”时,会丢弃限定符
您不应该只使用
重新解释cast
添加
常量。一个
重新解释\u cast
应该主要是:重新解释指针(或任何东西)

换句话说,如果您要从
const char*
转到
char*
(希望是因为有一个糟糕的API您无法更改),那么
const\u cast
就是您的朋友。这就是它的本意


但是如果您需要从
MyPODType*
转到
const char*
,则需要
重新解释cast
,不需要在其上加上
const_cast
,这很好。

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

UINT ThreadFunction(void* param)
{
    const MyClass* ptr = reinterpret_cast<const MyClass*>(param);
}
UINT线程函数(void*param)
{
const MyClass*ptr=重新解释强制转换(参数);
}

有一件事需要记住:不能使用
常量强制转换
使
常量
变量可写。如果常量引用引用非常量对象,则只能使用它从常量引用中检索非常量引用。听起来很复杂?例如:

// 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;
//有效:
int x;
int const&x1=x;
const_cast(x1)=0;
//无效:
int const y=42;
int const&y1=y;
常数(y1)=0;
事实上,这两种方法都会被编译,有时甚至会“起作用”。但是,第二种方法会导致未定义的行为,并且在许多情况下,当常量对象被放入只读内存时,会终止程序

也就是说,还有一些事情:
reinterpret\u cast
是最强大的施法,但也是最危险的施法,所以除非你必须使用,否则不要使用它。当您需要从
void*
转到
sometype*
时,请使用
static\u cast
。当走相反的方向时,使用内置的隐式转换或使用显式的
静态\u转换
。与添加或删除
const
类似,const也是隐式添加的。关于
重新解释cast
,另请参见讨论一种不太粗俗的替代方案的讨论


Uli

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

但是,当我们需要向类型添加常量时。我们为什么要这么做

比如说,

void PrintAnything(void* pData)
{
    const CObject* pObject = reinterpret_cast<CObject*>(pData);
    // below is bla-bla-bla.
}
void打印任何内容(void*pData)
{
const CObject*pObject=重新解释(pData);
//下面是布拉布拉布拉布拉。
}
重新解释演员与“常量”无关

const_cast意味着两件事。 第一个是从类型中删除常量,另一个是给出其代码的明确性。因为您可以使用C样式的强制转换来使用它,但这并不明确,因此不建议这样做


它们的功能不同。这是完全不同的。

@ClossVorters:你能让我看看回答这个问题的重复问题吗?
const\u cast
还包括添加/删除
volatile
@MikeDeSimone:当然可以,但我目前的重点只是constness,这句话应该读一下“…如果您
重新解释强制转换
结果返回到原始类型…”请参阅
5.2.10重新解释强制转换
当类型为“指向T1的指针”的PRV值转换为类型“指向cv T2的指针”时,如果T1和T2都是标准布局类型(3.9),则结果为静态强制转换(静态强制转换(v))T2的对齐要求并不比T1严格。
。因此,似乎可以使用reinterpret cast添加常量。非常量对象始终可以隐式转换为co