看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《tinlans ( )》之銘言: : ※ 引述《nowar100 (拋磚引玉)》之銘言: : : 分享一下我之前聽過的概念 : : C++設計這四種轉型,是為了防止PG做了不是自己想做的動作 : : 例如通常會設成const,就是希望不要去動到他的值 : : 但是這時候PG有這個必要性的時候,他就必須要用const_cast : : 這意義代表著PG必須自己清楚的了解,自己正在做"把const剝掉"這種危險事 : : static_cast是最普通的情況,基本上就是值互轉都是用這個 : : 例如int轉char,int轉double等等 : 只要你有 100% 的把握, : 向下轉型也是可以用這個, : 典型的應用例子就是 Curiously Recurring Template Pattern (CRTP), : 在這種狀況下不但可以大膽的用 static_cast 把 Base * 轉成 Dervied *, : 還能省下 RTTI 機制造成的 overhead。 : : dynamic_cast是用於多型的時候,在run-time時決定是否可以真的這樣轉 : : 例如將Based*轉成Derived* : 要再次強調的部分就是「用於多型的時候」, : C++ 根據多型性可以把 class 區分為 polymorphic class 跟 non-polymorphic class, : 所謂的 polymorphic class 內必定至少要有一個 virtual function, : 沒有 virtual function 的 class 就沒有對應的 virtual table, : 沒有對應的 virtual table 就代表沒有對應的 type info 欄位, : 也就是 RTTI 的所有機制在 non-polymorphic class 上無法作用。 : 以上面講的 CRTP 為例, : 大部分使用 CRTP 的 Base 是不帶有 virtual function 的, : 所以在這種狀況下寫 dynamic_cast<Dervied *>(ptrToBase) 會無法通過編譯, : 這點很多初學 dynamic_cast 的人會看不懂錯誤訊息; : 一般來說希望使用 dynamic_cast 等 RTTI 機制的話, : Base 至少就需要有一個 virtual function, : 如果找不到的話那首選對象就是 virtual destructor。 : STL 的 containers 都不具有 virtual function, : 所以試圖以多型的方式使用它們就是不可能的, : dynamic_cast 當然也是無法作用, : 所以 public 繼承 STL containers 一般來說可以視為觀念錯誤, : 在 code 裡出現這種東西是一個很大的警訊。 : : const_cast是用於剝掉const屬性 : : 例如const char*轉成char* : 用 const_cast 剝掉 const 雖然總是可以在 compile-time 運作, : 但也是要小心, : 這個前提是你必須 100% 確定你要轉的東西原本就不是 const, : 否則 run-time 的行為不可預測, : compiler 可以把任何最初就是 const 的變數或物件安排在 read-only 區段, : 對這種東西做 const_cast 再進行寫入可能會讓程式當掉, : 當然也有一定的機率可以正常運作 (視平台和編譯環境而定); : 合理的 const_cast 常出現在 operator overloading 的實作上, : 讓 const 跟 non-const 的版本能 reuse 同一份 code。 : : 至於reinterpret_cast這東西很危險,通常也不太會用到 : : 像是int*轉成char*,意義是"重新解析這個東西" : : 通常是在寫很底層,硬要用自己想要的觀點去存取資料結構,才會用到 : : 至於void*是萬用型態,是個特例,所以可以用static_cast轉 : : 至於C-style轉型,就是這四種的混合體,也就是暴力轉 : : C++故意將轉型分成四種,就是希望PG自己負起轉型的責任 : : PG使用不同的_cast的當下,必須清楚的知道自己在做什麼 : : 也因此,通常C++的PG不應該去用C-style的轉型 在去年12月初的時候, 因為看了一些書有很多大量的casting 覺得不是很懂 所以就開始大量地 survey C++ casting 的一些資訊跟一些觀念 來搞懂 C++ named casting 的四種轉法 下面是我在我部落格做的筆記來跟大家分享 http://ot-note.logdown.com/posts/173174/note-cpp-named-type-convertion -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 115.43.44.133
xvid:推! 01/07 23:56
Bencrie:推筆記 :) 01/07 23:58
sa074463:原來這篇是你的 推XD 01/08 00:20
purpose:cast 其實通常指 explicit conversion,補充一下 01/08 01:39
MetalChao:推! 01/08 09:58
shaopin:感恩, 大家一起進步 01/08 12:52
rant:整理的很清楚!! 01/08 13:22
damody: 01/08 17:28