【爲何要使用泛型】算法
經過泛型能夠定義類型安全的數據結構(類型安全),而無須使用實際的數據類型(可擴展)。這可以顯著提升性能並獲得更高質量的代碼(高性能),由於您能夠重用數據處理算法,而無須複製類型特定的代碼(可重用)。在概念上,泛型相似於 C++ 模板,可是在實現和功能方面存在明顯差別。安全
考慮一種普通的、提供傳統 Push() 和 Pop() 方法的數據結構(例如,堆棧)。在開發通用堆棧時,您可能願意使用它來存儲各類類型的實例。您可使用基於 Object 的堆棧,這意味着,在該堆棧中使用的內部數據類型是難以歸類的 Object,而且堆棧方法與 Object 交互:數據結構
上述容器可按下述方式使用:性能
基於 Object 的解決方案存在兩個問題。blog
第一個問題是性能。在使用值類型時,必須boxing & unboxing。裝箱和取消裝箱都會根據它們本身的權限形成重大的性能損失,可是它還會增長託管堆上的壓力,致使更多的垃圾收集工做,而這對於性能而言也不太好。即便是在使用引用類型而不是值類型時,仍然存在性能損失,這是由於必須從 Object 向您要與之交互的實際類型進行強制類型轉換,從而形成強制類型轉換開銷。內存
基於 Object 的解決方案的第二個問題(一般更爲嚴重)是類型安全。由於編譯器容許在任何類型和 Object 之間進行強制類型轉換,因此您將丟失編譯時類型安全。例如,如下代碼能夠正確編譯,可是在運行時將引起無效強制類型轉換異常: 開發
您能夠經過提供類型特定的(於是是類型安全的)高性能堆棧來克服上述兩個問題。對於整型,能夠實現並使用 IntStack。對於字符串,能夠實現 StringStack。字符串
遺憾的是,以這種方式解決性能和類型安全問題,會引發第三個一樣嚴重的問題 — 影響工做效率(沒法重用)。編寫類型特定的數據結構是一項乏味的、重複性的且易於出錯的任務。在修復該數據結構中的缺陷時,您不能只在一個位置修復該缺陷,而必須在實質上是同一數據結構的類型特定的副本所出現的每一個位置進行修復。此外,沒有辦法預知未知的或還沒有定義的未來類型的使用狀況,所以還必須保持基於 Object 的數據結構。編譯器
【什麼是泛型】編譯
在一些 C++ 編譯器中,在您經過特定類型使用模板類以前,編譯器甚至不會編譯模板代碼。當您確實指定了類型時,編譯器會之內聯方式插入代碼,而且將每一個出現通常類型參數的地方替換爲指定的類型。此外,每當您使用特定類型時,編譯器都會插入特定於該類型的代碼,而無論您是否已經在應用程序中的其餘某個位置爲模板類指定了該類型。C++ 連接器負責解決該問題,而且並不老是有效。這可能會致使代碼膨脹,從而增長加載時間和內存足跡。
【一些泛型應用】