[英]Extending libraries in C++
是否可以在沒有源代碼的情況下從C ++庫擴展類? 標題是否足以允許您使用繼承? 我正在學習C ++並且正在進入理論。 我會測試這個,但我不知道怎么做。
簡短回答是的,最終你可以。
答案很長 : 警告:以下文字可能會傷害兒童敏感的OOP整體主義者。 如果您感覺或保持成為其中之一,請遠離這個答案:我的每個人都會更容易生活
讓我揭開一個秘密:STL代碼只不過是帶有頭文件和庫的常規C ++代碼,就像你的代碼可以 - 而且很可能 - 那樣。 STL的作者只是程序員,就像你一樣。 它們在編譯器方面並不特別。 他沒有任何超級大國。 他們像你一樣坐在他們的廁所上,做你正在做的事情。 不要過分誤解他們。
STL代碼遵循與您自己編寫的代碼完全相同的規則:被覆蓋的內容將被調用而不是基礎:總是如果它是虛擬的,並且僅根據其引用指針的靜態類型,如果它不是虛擬的,就像其他所有一塊C ++代碼。 不多也不少。
重要的是不要破壞關於STL名稱約定和語義的設計問題,以便每次進一步使用代碼都不會混淆人們的期望,包括你自己,10年后閱讀代碼,不記得某些決定。
例如,重寫std::exception::what()
必須返回一個解釋性持久性C字符串(如STL文檔所述),而不是添加意外的其他模糊操作。
此外,重寫流或流操作符應該完成整個設計(你真的需要覆蓋流或只是streambuffer或只是添加一個特定的facet到它所灌輸的語言環境 ?):換句話說,研究不僅僅是“ “但它的所有”世界“的設計,以正確理解它是如何與周圍的東西一起工作的。
最后,但並非最不重要的是,最具爭議的方面之一是容器和一切沒有虛擬析構函數的東西。
我的觀點是關於“經典的OOP規則:不要得到沒有虛擬析構函數”的噪音過度膨脹:只是不要指望一cow
成為一horse
只是因為你把saddle
放在它上面。
如果你需要(真的需要)一個用std :: string完全相同的接口來管理一個字符序列的類,它能夠隱式轉換為std :: string,並且有更多的東西,你有兩種方法:
std:string
並重寫所有112(是的:他們超過100)方法的功能,除了調用它們之外什么都不做,並確保你仍然處女與另一個善良的婚姻男孩程序員的代碼,或者...... std::string
。 你唯一要放棄的是你與一個完整主義者結婚的可能性。 你甚至可以發現它不一定是個問題:你甚至遠離被他殺死的風險! 你唯一需要注意的是, std::string
不是多態的,你的派生就會這樣做,所以不要指望和std::string*
或std::string&
引用yourstring
來調用你的方法,包括析構函數,其他方法都沒有特別的尊重; 它只是遵循完全相同的規則。 但是......嘿,如果你嵌入並編寫一個隱式轉換運算符,你將獲得完全相同的結果,不會再少了!
規則很簡單:不要讓自己成為虛擬的析構函數,也不要假裝“OOP替換原則”來處理不是為OOP設計的東西,一切都會正確。
隨着所有OOP整體主義者在他們永恆的睡眠中保持着自己的睡眠,你的代碼將會起作用,而他們仍在重寫100+ std :: string方法,只是為了嵌入它。
是的,該課程的宣言足以從中獲得。
當您鏈接到庫時,其余代碼將被選中。
是的,您可以在標准C ++庫中擴展類。 頭文件就足夠了。
一些例子:
std::exception
類以創建自定義異常 但是你要注意的一件事是不要擴展沒有virtual destructor
。 示例是std::vector
, std::string
編輯:我剛剛發現了另一個關於這個主題的SO問題通過繼承來擴展C ++標准庫?
只有一個頭文件足以從該類繼承。
C ++程序分為兩個階段:
因此,只要您具有頭文件( 編譯所需 )和庫( 鏈接所需 ),您就可以從類派生。
但請注意,必須要注意該類是否確實用於繼承。
例如:如果您有一個非virtual
析構函數的類,那么該類不適用於繼承。 就像所有標准庫容器類一樣。
簡而言之,只要擁有類的接口就足以進行派生,但類的實現和設計語義確實起着重要的作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.