2013-01-11 32 views
6

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

const_cast用于删除或添加const到一个变量及其唯一可靠,定义和合法的方式来消除常量。 reinterpret_cast用于更改类型的解释。

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

我明白,使用reinterpret_cast甚至添加常量不是理智的,但它会是一个UB或潜在的使用reinterpret_cast添加常量的定时炸弹?

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

很大程度上,你的reinterpret_cast唯一能把握的是,如果 你把结果返回到原来的类型,你会得到确切 相同的价值。

所以,如果我添加使用reinterpret_cast的,如果你的reinterpret_cast结果回到原来的类型,它应该产生回原来的类型,不应该UB,但违反了一个事实,就是只能用const_cast常量性去除常量性

在一个单独的说明,标准保证了您可以使用重新解释的情况下

5.2.10重释投(7)......当类型的prvalue v常量性增加“指向T1的指针”被转换为类型“指向cv T2的指针”,结果是 的static_cast(的static_cast(V))如果两个T1和T2是 标准布局类型(3.9)和T2的对准要求是 并不比T1的严格........

+0

@clossvoters:你可以请参考我的重复问题,回答这个问题吗? – Abhijit

+1

'const_cast'也涵盖'volatile'的添加/删除。 –

+0

@MikeDeSimone:是的,但我当前的重点只是稳定 – Abhijit

回答

9

reinterpret_cast更改对象内数据的解释。 const_cast添加或删除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 
+1

请参阅'5.2.10重新解释转换' :当T1和T2都是标准的时,将“指向T1”的类型的prvalue v转换为类型“指向cv T2的指针”时,结果为static_cast (static_cast (v))对于T2的要求,布局类型(3.9)和对齐 并不比T1的要求更严格。所以看来你可以使用reinterpret强制转换添加const。 – Abhijit

+1

非常量对象总是可以隐式转换为常量而不需要任何强制转换。我不明白为什么'reinterpret_cast'应该是这个规则的一个例外。 – StackedCrooked

3

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

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

但是,如果你需要去从MyPODType*const char*,你需要reinterpret_cast,它的对我非常好,不要求在它上面的一个const_cast

0

在那里我可以用常量性的reinterpret_cast有关想到的唯一地方是传递一个const对象到接受空指针的API时 -

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

有一两件事要牢记:您不能使用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; 

实际上,这些都会编译,有时甚至是“工作”。但是,第二个会导致未定义的行为,并且在常量对象被放置在只读存储器中时,在很多情况下会终止程序。

这就是说,更多的东西: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的讨论,其中讨论了一个不太讨厌的替代方案。

乌利

0

是的,如你所知,const_cast会意味着它从一个特定的类型消除常量性。

但是,当我们需要添加constness到一个类型。我们必须这样做吗?

例如,

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

的reinterpret_cast无关与 '常量'。

const_cast表示两件事。 第一个是从一个类型中去除常量,另一个是给它的代码显式性。因为你可以使用C风格强制转换,但这不是明确的,所以不推荐。

它们不起作用。它绝对不同。