2011-03-04 99 views
0

可能重复:
Why do we have reinterpret_cast in C++ when two chained static_cast can do it's job?为什么reinterpret_cast的仍然是在使用时有危险

我一直认为我不应该使用的reinterpret_cast或const_cast会在指针的情况下指针的转换。只有dynamic_cast应该使用。因为其他演员将来可能会产生问题。所以我的问题是为什么reinterpret_cast或其他强制转换已经从C++标准中删除。

+1

重复的[?为什么我们在C++的reinterpret_cast当两分链式的static_cast可以做的工作(http://stackoverflow.com/questions/ 5025843 /为什么-DO-我们具备的,重新诠释 - 现浇C-当两链静态铸造灿-DO-其-J)。基本答案是:因为其他演员表达式无法完成的事情。 – 2011-03-04 04:39:55

+0

请参阅本主题:[为什么当两个链接的static_cast可以完成它的工作时,我们在C++中使用reinterpret_cast](http://stackoverflow.com/questions/5025843/why-do-we-have-reinterpret-cast-in- c-when-two-chained-static-cast-can-do-its-j) – Nawaz 2011-03-04 04:40:14

+0

@James::D .... – Nawaz 2011-03-04 04:40:48

回答

2

他们很危险,但有时你需要他们。

C++不知道用于删除对新用户有危险的构造。我们会让你与那些剪刀一起运行(同时吃蛋糕)。

什么使他们很好是危险的代码突出,所以很容易发现。因此,当人们进行代码审查时,他们可以迅速发现危险的东西,并加入更多检查的细节。

+0

+1提到它如何使代码伸出。使用C++与C风格转换的充分理由 – seand 2011-03-04 04:44:29

5

因为有时候你需要一个能做reinterpret_cast做什么的演员。至于dynamic_cast,我差不多从来没有使用此演员;这只适用于从父类型转换为更多派生类型。大多数情况下,我可以证明我正在使用哪种儿童类型,并使用static_cast。我也使用static_cast进行编译时类型转换,例如从signed到unsigned整数。

static_cast而不是dynamic_cast,是最常见的演员。如果您的设计过于依赖dynamic_cast,那么在大多数情况下,这是一种代码异味,指示您的类层次结构违反了LSP。

+0

在C++中,我发现自己很少使用dynamic_cast。 – seand 2011-03-04 04:51:27

2

在现实世界中,您经常需要以编译器/运行时无法验证的方式投射指针。例如,在pthread中,您将一个void *传递给新线程的启动例程。有时候这个参数实际上是一个类?编译器无法告诉。这是那些“现实生活”问题之一。

顺便说一句,我发现自己很少使用dynamic_cast。我主要用于catch块中的异常类型的抓取。

0

很多危险的操作,尽管通常应该避免,但确实有罕见的合法用法。此外,关于语言特性和API的经验法则是,一旦它存在,就无法摆脱它;从C++语言中删除一个特性有可能会破坏很多现有的C++代码。通常情况下,功能的删除需要证明它没有被使用,或者使用非常有限,以至于消除它的成本影响会很小。甚至几乎从未使用过的trigraphs(除非你在IBM),并且人们想要摆脱的trigraphs幸存下来。这些不同的演员和其他通常危险的操作都被使用,而不仅仅是三字母。

1

使用reinterpret_cast在不相关的指针类型之间进行投射。

使用static_cast进行显式支持的转换。

使用dynamic_cast将一种类型的指针转​​换为派生类型的指针。

如果您知道指向父类型的指针指向子类型,则可以安全地将父类型的static_cast安全地指向子类型。从子类型指针到父类型指针的转换是隐式的,不需要显式转换。

一个从我自己的代码库的reinterpret_cast例如:

unsigned int CTaskManager::CWorker::WorkerMain(void* Parameters) 
{ 
    CWorker* This = reinterpret_cast<CWorker*>(Parameters); 
    // ... 
    } 

bool CTaskManager::CWorker::Initialize() 
{ 
    // ... 

    // Create worker. 
    m_ThreadHandle = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &(WorkerMain), this, 0, NULL)); 

    // ... 

} 
相关问题