const_cast vs reinterpret_cast

时间:2013-01-11 06:01:13

标签: c++ casting const reinterpret-cast

参考SO C ++ FAQ When should static_cast, dynamic_cast and reinterpret_cast be used?

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

我理解为什么一个const变量应该只使用const_cast转换为非const,但是我无法用reinterpret_cast代替const_cast来找出问题的合理理由来增加constness。

据我所知,使用reinterpret_cast甚至添加const不是理智但是使用reinterpret_cast添加常量会是UB还是潜在的定时炸弹?

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

  

很大程度上,reinterpret_cast的唯一保证是if   您将结果转换回原始类型,您将得到确切的结果   相同的价值。

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

在单独的注释中,该标准保证您可以使用重新解释案例

添加常量
  

5.2.10重新解释强制转换(7)......当“指向T1的指针”类型的prvalue v转换为“指向cv T2的指针”类型时,结果是   static_cast(static_cast(v))如果T1和T2都是   标准布局类型(3.9)和T2的对齐要求是   没有比T1更严格........

5 个答案:

答案 0 :(得分:10)

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

  

因此,如果我使用reinterpret_cast添加constness,并且如果你将结果重新解释为返回原始类型,它应该返回原始类型并且不应该是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

答案 1 :(得分:4)

您不应只是const一起添加reinterpret_castreinterpret_cast应该主要是:重新解释指针(或其他)。

换句话说,如果您从const char*转到char*(希望因为API不好而无法更改),那么const_cast就是您的朋友。这真的是它的全部目标。

但是如果您需要从MyPODType*转到const char*,则需要reinterpret_cast,而且不需要const_cast就可以了。< / p>

答案 2 :(得分: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++ When should we prefer to use a two chained static_cast over reinterpret_cast的讨论,其中讨论了一种不那么强硬的替代方案。

乌利

答案 3 :(得分:0)

我可以想到将reinterpret_cast与const-ness相关联的唯一地方是将const对象传递给接受void指针的API -

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

答案 4 :(得分:0)

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

但是,当我们需要为一个类型添加constness时。我们有这个理由吗?

例如,

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

reinterpret_cast与'const'无关。

const_cast意味着两件事。 第一个是从类型中删除constness,另一个是为其代码显示。因为您可以使用C样式转换来使用它,但这不是明确的,因此不推荐使用。

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