簡體   English   中英

在Objective-C和C ++之間進行比較

[英]casting comparison between Objective-C and C++

好的,所以這可能是一個學術問題。 有人能告訴我C ++的投射操作符是否/如何轉換為Objective-C ...或者如何/為什么它們沒有必要?

我已經離開了幾年的C ++循環,似乎每次我轉身他們添加一些新的關鍵字。 我最近介紹了C ++的各種轉換操作符reinterpret_cast,static_cast,dynamic_cast和const_cast。 當這些情況出現時你需要使用所有這些類型的演員表時,我有點模糊。

我已經使用Objective-C一兩年了,對它感覺相當舒服。 (直到那時候大部分都是C人)。 我試圖理解為什么C ++似乎具有所有這些復雜性。 換句話說,什么是Objective-C缺少它似乎沒有(或需要?)這么多的鑄造類型?

查看問題的答案 關於每種演員的意義。

什么是Objective-C缺少它似乎沒有(或需要?)這么多的鑄造類型?

C ++更注重類型安全而不是C. 許多演員操作符被添加以使許多不同的演員意圖清晰 (並且由於其丑陋的形式而阻止人們使用它)。 和,

  • 在Objective-C中沒有const對象( const NSObject* ),並且與C ++不同,其他const參數沒有那么強調,因此const_cast是無用的。

  • Objective-C實例總是使用動態類型,因此不需要dynamic_cast (ObjC中的類型檢查通常使用-isKindOfClass:

  • static_castreinterpret_cast在C中是相同的,但在C ++中卻不是這樣。 因為C ++支持多重繼承(ObjC中缺少),所以指針轉換並不像no-op那么簡單:

     #include <cstdio> struct A { int x; A() : x(12) {} }; struct B { int y; B() : y(33) {} int get() const { return y; } }; struct C : A, B { int z; C() : A(), B(), z(41) {} }; int main () { C* c = new C; printf("%d\\n", c->get()); // 33 printf("%d\\n", static_cast<B*>(c)->get()); // 33 printf("%d\\n", reinterpret_cast<B*>(c)->get()); // 12 } 

看一下CPlusPlus.com的文章,它詳細介紹了各種類型轉換方法。

  1. reinterpret_cast將任何指針類型轉換為任何其他指針類型,甚至是不相關的類。 操作結果是從一個指針到另一個指針的值的簡單二進制副本。 允許所有指針轉換:既不檢查指向的內容,也不檢查指針類型本身。
  2. static_cast可以執行指向相關類的指針之間的轉換,不僅可以從派生類到其基類,還可以從基類到其派生類。 這確保了如果轉換了正確的對象,至少類是兼容的,但是在運行時期間不執行安全檢查以檢查被轉換的對象實際上是否是目標類型的完整對象。
  3. dynamic_cast只能用於指針和對象的引用。 其目的是確保類型轉換的結果是所請求類的有效完整對象。
  4. const_cast是一種類型的轉換,它操縱對象的常量,要么被設置要么被刪除。 例如,為了將const參數傳遞給期望非常量參數的函數

從廣義上講,它們允許程序員聲明他們的意圖並確切地斷言他們試圖通過強制轉換實現的目標。 它們還有助於在編譯時標記出錯錯誤,否則只會在運行時顯示(如果你很幸運!)。

我自己沒有使用過目標C,所以我不能評論為什么那種語言可能沒有它們。

事實上,有幾種截然不同的類型的演員表,具有不同的意圖,並且希望能夠明確地指定該意圖,以便您不小心做錯了。 例如,您可能正在將const int*const char*以對原始字節進行操作,並且無意中也會刪除const 因此,在C ++中,使用reinterpret_cast將指針從一個不相關的類型更改為另一個類型,而轉換const只能通過const_cast完成。 如果你嘗試const void* p; reinterpret_cast<char*>(p) const void* p; reinterpret_cast<char*>(p) ,你會收到一個錯誤。

需要dynamic_cast來可靠地向下轉換事物(使用運行時檢查),並且還用於交叉轉換(即,將Base1*類型的指針賦予實際類型Derived的對象,該對象繼承自Base1*Base2* ,以便能夠直接轉換為Base2* ;對於引用也是如此 - 這對於“接口”特別有用。

static_cast是其余部分 - 值轉換(int < - > float等),對象指針/引用的向上轉換以及未經檢查的向下轉換。 它也是最常用的,盡管一些樣式指南盡可能在所有對象指針/引用強制轉換上使用dynamic_cast

一般來說,理由似乎是:兩個最危險的操作(投射到指針到無關類型,並拋棄常量)都有自己的專用投射操作符,以防止它們意外發生的任何可能性。 接下來,為演員需要運行時查找的情況提供了一個新的運算符。 最后,還提供了另一個新的操作員來覆蓋任何剩余的地面。 舊的C型“通用”鑄造操作員實際上已被棄用。

現在,為什么Obj-C不“需要”它們。 可以說,它實際上可以使用const_castreinterpret_caststatic_cast之間的區別 - 但顯然,這些差異被視為沒有增加足夠的值來擴展核心C語言。 它不需要dynamic_cast ,因為它沒有多重繼承(協議有些不同),而類型檢查則通過isa方法完成。

C(和物鏡C)演員是重型橡膠槌,C ++演員是一組鑿子。 它們允許您聲明您想要制作的特定類型的轉換,並讓編譯器幫助您僅強制執行特定類型的轉換。 由於演員陣容可能是危險的,因此每個演員陣容的有限范圍使他們更安全 - 而且更笨拙的語法被吹捧為一個優勢,因為它可以阻止過度使用演員陣容。

與Objective C完全不同的是dynamic_cast ,它執行額外的運行時檢查以確保對象在轉換為期望之前具有所需類型,並返回0或拋出異常(如果它不存在)。 它類似於在進行Objective C isKindOfClass之前在NSObject上調用isKindOfClass ,而在C ++世界中對於向下轉換非常有用。 但請注意,由於Objective C中的動態方法分派,您不必在向對象發送特定消息之前對其進行向下轉換,因此向下轉換的作用比在C ++世界中要小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM