我寫C++喜歡用繼承有問題么?
繼承啊,這玩意當時就覺得,C++就跟物理世界似的,最根上的類就是最原始的粒子,然後在這個基礎上一層層繼承下去,然後就形成一個美好的現實世界了……
不過,現實世界的動植物(生物)是需要進化的,所以,除了繼承還有基因突變呢,C++沒這機制。
所以,你寫C++,你喜歡繼承,你可以用,沒問題,前提是,你得保證你的每一個新類都是最完美的——完美的實現了所有角度的需求,還能完美的保證各方面的擴展,以便被繼承。
最終呢,你會得到一個完美的C++程序世界……
拭目以待吧。
繼承是強耦合。能不用就不要用
你有侵入式得雙鏈表,就可以通過鏈表結構的在timer中的地址偏移拿到timer對象的指針了。當然這是C語言開發的慣用做法。C++的經典做法是鏈表裡保存timer虛基類的指針,就要用到繼承。
軟體開發範式眾多,發展也很快,但是都遵循一個核心理念「高內聚,低耦合」。
指的就是模塊內的代碼盡量做同一件事情,而模塊之間盡量減少交互。繼承的通病是在「類」這個層面的模塊上引入了太強的耦合,尤其是濫用的情況比較普遍,所以不被喜歡。要是讀過上古神書「設計模式」,可以看看作者對於繼承的態度,很中肯。(當然繼承也存在逼格不夠高的因素)(劃掉)一般來講我們系統中會有一個業務模型的類實現,用來反應主要的業務邏輯。繼承經常用在這裡。比如對於遊戲步兵是個兵,對於倉儲西瓜是個貨,這種。這個叫主要業務模塊。
而圍繞在在這個主要業務模塊之外為了系統的運作還有很多模塊,比如做「日誌」的,做客戶端到服務端鏈接的,做批處理的。有些可以以非侵入的方式做,有些必須改主要業務邏輯的代碼。不管怎樣,都需要跟主要業務邏輯之間產生最小的耦合。
之於題目中的問題。
要不要繼承我覺得可以看你的這個繼承樹是不是主要業務邏輯?你要不知道怎麼看,那就看看子類的名字,是都叫xxxtimer么?如果是,你就告他們,我這個系統里都是timer,憑啥不讓我繼承自timer?
要不是,那可能就是你想給主要業務邏輯的代碼加timer的功能。那麼繼承就不太合適。因為你強迫主要業務邏輯的代碼依賴於「timer」這個父類的定義,這是一個很強的耦合。而用functor的辦法,被timer的類甚至可以不知道有「timer」這個類存在,只要有人負責告訴他怎麼更新就好。具體怎麼做需要知道具體的應用場景,也不太好說。總歸(在程序里)能少認識一個人(類)就少認識一個,低耦合。Because inheritance is so important in object-oriented programming, it is often highly
emphasized, and the new programmer can get the idea that inheritance should be usedeverywhere. This can result in awkward and overly complicated designs. Instead, you shouldfirst look to composition when creating new classes, since it is simpler and more flexible. Ifyou take this approach, your designs will be cleaner. Once you』ve had some experience, it will——&
雖然是一本寫Java的書,但是這裡在講面向對象的思想,而且作者也寫過&
multi 繼承 一般容易有問題(甚至可能是C++唯一能被詬病處)。多用些interface instead(if you have to)。
你需要先想清楚「public繼承」到底是什麼意思,然後再決定怎麼去設計,而不是看代碼怎麼好寫。
樓主的想法很好,可以自動避免無效資源的訪問 但是這樣使用繼承有幾個缺點,一個是業務類和timer並不是強繼承關係 會存在拓展的問題 而且使用起來也比較麻煩。至於生命周期的問題 如果項目不太好用智能指針實現弱回調 可以業務類保留其timer的id 在析構的時候用id去掉這個timer
樓主,不知道你這個定時器是怎麼實現了,靠譜不靠譜。
其次呢,你談到繼承和組合的問題。
我覺得,凡是高內聚,低耦合的方式都不差。
那麼最重要的問題是什麼呢?
你的定時器,在面對變局的時候,是牽一髮動全身,還是說,直接可以刪除掉這個定時器,
直接換成,新的定時器。 對整個環境沒有任何影響。
顯然,我覺得多線程+ 協程+class。項目的管理體系,都是圍繞協程管控。有助於巨型項目的千年大計。
局限在語法裡面的人,最終都被 未知所擊敗。
就像身處cpp98的人,不會想到cpp20.
身處cpp20的人,不會想到cpp999999999
一樣。那麼,我們在寫cpp代碼的時候,要明白。
一個代碼生成器是多麼的重要,語法糖沒有提供的,我們就用自己的編輯器去造嘛。
讓自己看懂,毫無意義。你沒了,知識就失傳了。
讓精英看懂,稍微有點意義,但是精英沒了,知識就失傳了。
讓百姓看懂,就很有意義了,因為百姓會一直在,永不失傳。
那麼回歸正題,理想和現實。
現實是,利用繼承實現的定時器,肯定不美,但是很實用。
理想中的定時器,肯定是 隨時可以替換掉,
不會說,基類被換了,改了,子類可能沒考慮到就出現了偏差。
那麼,先繼承實現功能,再慢慢將繼承的方式改為組合化。
跟現實一樣的道理,協作才是出路,靠家族。。只能在初期。想做大,必須海納百川。
也就是說專業化。那麼多寫協程方式的代碼,有助於編程思維的改變。
說實話沒看懂為什麼只有繼承了基類,析構的時候才會從mngr中刪除,這個功能不是基類本身就有的嗎,只不過你的基類是抽象類,用的人必須去繼承而已。你就按照陳碩大大的辦法,把抽象函數改為普通函數,在這函數里直接用std::function做回調會更好啊,用戶只要set一個回調進來就行了而不必要去繼承。在這個例子中,繼承帶來的問題就是導致系統中的類會急劇增多,而且還不好用...建議題主去看看《head first設計模式》,看完覺得意猶未盡再去看看四人組的《設計模式》
我來答一波,你那樣做感覺擴展性不好。如果我是你同事那不得理解你的timer類嗎,我直接給個類給你,你要什麼自己調不是很好嗎。這屬於兩個對象對接介面的問題,後面要添加功能擴展那個類不是更方便嗎,而且即便寫代碼那人離職了,每個人都容易維護呀。
做遊戲伺服器你們還沒禁用繼承么?貌似繼承效率比較低。這種搞仿函數(函數對象)才是王道吧。
這個事情沒有定論,沒有標準答案的!每個產品,模塊都是特別的,有自己的歷史,環境,用戶等等~~~我們只能選擇最合適的!
推薦閱讀:
※github 上有哪些遊戲或者遊戲開發相關的炫酷的user或者repo?
※noexcept標識符為什麼不這樣設計?
※C語言int型(2位元組)數據的值的範圍為什麼是-2^15~(2^15-1)?
※C++域作用符在函數聲明和定義中的意義?
※在 64 位平台開發時是否應盡量避免使用指針?