2011-03-04 101 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)); 

    // ... 

} 
相關問題