擊左上方藍色“ 一口Linux ”,選擇“ 設為星標 ”
? 【干貨】 Linux嵌入式知識點-思維導圖-免費獲取 ? 【就業】 一個可以寫到簡歷的基于Linux物聯網綜合項目 專業知乎潛水多年,還是要輸出一點東西,才能鞏固自己的知識。這第一篇文章說一下 C 語言中實現面向對象編程 的技巧。
方法 1:struct 定義數據,函數定義方法,struct 的指針作為函數首個參數傳入
<span leaf=""><span leaf=""><img data-imgfileid="100042192" src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/icRxcMBeJfcib1LaOTUuE81lqOz3JnibkJWDTtJG4hHia5Y8FSkV7YgibAIvAmD5oG5DsVqicRFytY64TSlX8VVAlcDw/640?wx_fmt=jpeg&amp;from=appmsg" data-type="jpeg" width="1270"/></span></span>
優點: 1. 直接明了,一眼知道干什么。2. 方便 IDE 中跳轉調試。
缺點: 命名特別的長,如果按照【<文件名>_<類名>_<方法名>】的命名規則,由于第一個參數的類型還需要以【<文件名>_<類名>】這樣格式寫一遍,所以很多函數的長度很容易就超過 100 個字符了,這樣使用工具自動格式化的時候,通常會分行顯示,不美觀。
方法 2:方法 1 簡潔版,加上一些簡單的輔助宏,使定義變簡短
<span leaf=""><span leaf=""><img data-imgfileid="100042193" src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/icRxcMBeJfcib1LaOTUuE81lqOz3JnibkJW3sZ0uUWLBwU1xOgoIQT7HvzU3mOoZ9VRGkUUCPATK5VJOOmgwbSjZg/640?wx_fmt=jpeg&amp;from=appmsg" data-type="jpeg" width="1594"/></span></span>
優點: 1. 命名和調用不需要寫那么多東西,不會再忘記需要將第一個參數寫成 struct 的指針了。2. 將類名單獨拆分出來,容易辨認出該函數是在定義類的方法。
缺點: 將長的函數名拆分了,IDE 難以進行定義跳轉,寫得爽了,但是調試起來很麻煩,只能通過搜索或者正則表達式找到方法的具體定義處。
方法 3:struct 定義數據及方法原型
<span leaf=""><span leaf=""><img data-imgfileid="100042194" src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/icRxcMBeJfcib1LaOTUuE81lqOz3JnibkJW9tTqGicd6iaf4CXk544EWFFf3iaJXbCgbvjJQ9JKJWewM0S37Anibt7Kicg/640?wx_fmt=jpeg&amp;from=appmsg" data-type="jpeg" width="1284"/></span></span>
優點: 1. 調用 init 或 get_area 等對象方法的時候,無需知道對象的類型,寫 obj.init 即可。
缺點: 寫法冗長,需要手動初始化函數指針,而且定義了方法函數的同時,還得復制一遍函數 prototype 作為 struct 的函數指針。一旦函數 prototype 有所改動,需要修改多個地方。所以這個寫法通常需要搭配宏去使用,將寫法簡化。
方法 4:手動寫虛函數表 ,虛函數表用來將函數指針定位到具體函數中
<span leaf=""><span leaf=""><img data-imgfileid="100042198" src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/icRxcMBeJfcib1LaOTUuE81lqOz3JnibkJWGBfJlI0NytAR2b8GwTdDbX2o3MAXedyDJJ4d0zn6yfrm7SLjgY7Img/640?wx_fmt=jpeg&amp;from=appmsg" data-type="jpeg" width="1284"/></span></span>
優點: 1. 調用 init 或 get_area 等對象方法的時候,無需知道對象的類型,寫 obj.init 即可。2. 函數原型需要修改時,改動虛函數表即可。
缺點: 多了一個虛函數表結構體聲明以及定義,代碼變復雜,占用的空間變大。
方法 5:方法 4 pro 版,使用輔助宏使定義變簡短
<span leaf=""><span leaf=""><img data-imgfileid="100042197" src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/icRxcMBeJfcib1LaOTUuE81lqOz3JnibkJWr7DEf9ibhTxdstl69QrHQOjBaHq1wg4zhXsiabConibREF05uKp9r0uVw/640?wx_fmt=jpeg&amp;from=appmsg" data-type="jpeg" width="1608"/></span></span>
優點: 通過一些宏增強了可讀性,并簡化了需要寫的代碼。
缺點: 仍然需要手動寫虛函數表,容易出錯。
方法 6:方法 4 pro max 版,使用復雜的輔助宏,自動構建虛函數表 可以參考 interface99 或 macoop:
他們的作用是通過復雜的宏,幫你把虛函數表構建好了。
如果使用 macoop,那么代碼可以寫成這樣:
<span leaf=""><span leaf=""><img data-imgfileid="100042202" src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/icRxcMBeJfcib1LaOTUuE81lqOz3JnibkJWiaiaNzprhmzSWpfP3ZnuOXar6CEHehnwIMicaq8ASI726ybfMl1hVicq1w/640?wx_fmt=jpeg&amp;from=appmsg" data-type="jpeg" width="1608"/></span></span>
優點: 簡化了對象的定義和虛函數表的定義,寫起來爽。
缺點: 1. 宏很復雜,使用預編譯器魔法,不好理解。2. 不能使用 IDE 跳轉定義,調試難
方法 7:目前個人使用,基于方法 2 的改良版
<span leaf=""><span leaf=""><img data-imgfileid="100042204" src="https://mmbiz.qpic.cn/sz_mmbiz_jpg/icRxcMBeJfcib1LaOTUuE81lqOz3JnibkJWibP2HeicsZlpnTRt58Gpx3qtI4JDXV3ASN3X1vgGBnjQXmAbh9lZZibrA/640?wx_fmt=jpeg&amp;from=appmsg" data-type="jpeg" width="8804"/></span></span>
優點: 1. 簡潔,只需增加 3 個宏。2. 將類名與函數名通過 "__" 連接在一起,增強可讀性的同時,方便 IDE 進行定義跳轉,方便調試。
缺點: 1. 需要在方法函數體內手動將 void * 參數轉換為 struct 的指針類型。2. 調用時需要知道具體的類名。
總結 其實在 C 語言中可以直接實現面向對象的編程思想。
可以把一個 C 文件看作為一個類,文件名即類名。
static 的變量為 private 變量,static 的函數為 private 方法,global 的變量為 public 變量,global 的函數為 public 方法。本文中寫的技巧只是把面向對象給更直觀地表現出來而已。
不知道各位有什么看法,或者有什么更好的方法或者實現?
作者:涅哀
https://www.zhihu.com/question/551191065/answer/1889832145456973627
關注,回復【 1024 】海量Linux資料贈送
精彩文章合集
文章推薦