[問題] 純C下的結構化跟函數指標問題

看板C_and_CPP作者時間6年前發表 (2019/02/19 15:12), 6年前編輯推噓7(7022)
留言29則, 8人參與, 6年前最新討論串1/1
開發平台(Platform): (Ex: Win10, Linux, ...) 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) GCC 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) 問題(Question): 在純C(目前編譯器有支援到C99)的環境下,我試著以下述方式進行資料封裝: void DoorOpen(void) { // ... } typedef struct { void (*open)(void); void (*close)(void); } CAR_DOOR; CAR_DOOR car_door = { .open=,DoorOpen .close=NULL, } typedef struct { CAR_DOOR* door; CAR_ENGINE* engine; } CAR; CAR car = { .door=&car_door, .engine=NULL }; 使用時就以下面的方式操作 car.door.open(); car.engine.enable(); 優點: 1.使用時感覺比較結構化。 2.如果有另外一個主結構叫home,只要把car跟home放在不同的檔案(.h/.c), DoorOpen這類函式只要宣告成static,命名就可以相同,不用為了取名字煩 惱,或是把函式名字拉得很長。 缺點: 1.寫起來有夠麻煩。 2.door、engine都必須宣告出來,其他結構的指標才能指向它。 3.如上面例子中,CAR_ENGINE結構或是CAR_DOOR下的close函式我還沒想到要怎麼實現 前,如果只給NULL,不小心存取到會發生問題。 4.比起直接呼叫函式效率應該會差一些,不過在我的應用上這些差異可以忽略。 請問是不是有什麼方法可以改善克服這些缺點,或是有更好的做法寫出較具維護性的 code呢? 謝謝大家。 餵入的資料(Input):預期的正確結果(Expected Output):錯誤結果(Wrong Output):程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔) 補充說明(Supplement): 無 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.250.44.253 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1550589149.A.813.html ※ 編輯: icetofux (111.250.44.253), 02/19/2019 23:13:14 ※ 編輯: icetofux (111.250.44.253), 02/19/2019 23:14:12

02/20 00:19, 6年前 , 1F
研究一下C語言的歷史,然後改用C++
02/20 00:19, 1F

02/20 00:31, 6年前 , 2F
我好像有一篇是跟你有一樣的困擾 你參考看看
02/20 00:31, 2F

02/20 00:34, 6年前 , 3F
02/20 00:34, 3F

02/20 02:15, 6年前 , 4F
你CAR那邊可以考慮不用CAR_DOOR*,而直接用CAR_DOOR
02/20 02:15, 4F

02/20 02:15, 6年前 , 5F
然後再搭配一些init function或是init macro
02/20 02:15, 5F

02/20 02:15, 6年前 , 6F
應該可以解決你的問題
02/20 02:15, 6F

02/20 06:09, 6年前 , 7F
我會寫init ,marco 幾年後誰來維護
02/20 06:09, 7F

02/20 06:11, 6年前 , 8F
手邊十個bug還要花時間弄懂你寫的
02/20 06:11, 8F

02/20 06:11, 6年前 , 9F
對團隊來說是地雷
02/20 06:11, 9F

02/20 06:13, 6年前 , 10F
太多fuction根本不是問題,ide就解決了
02/20 06:13, 10F

02/20 11:35, 6年前 , 11F
比起物件導向的思維,函數式(FP)的作風更適合C
02/20 11:35, 11F

02/20 11:38, 6年前 , 12F
用C寫OO只要一個結構配一堆函式就好了,想太多都是徒勞
02/20 11:38, 12F

02/20 12:50, 6年前 , 13F
你在呼叫open, close ...的時候如果要指定哪個門或哪台
02/20 12:50, 13F

02/20 12:50, 6年前 , 14F
科的門,最後還是要把指標傳進去,C這樣用真的會比較方
02/20 12:50, 14F

02/20 12:50, 6年前 , 15F
便嗎?
02/20 12:50, 15F

02/20 13:55, 6年前 , 16F
你先從 Abstract Data type (ADT) 去設計, 我發現很
02/20 13:55, 16F

02/20 13:55, 6年前 , 17F
多書在教人寫扣的時候都忽略抽象化這個觀念, 先提供
02/20 13:55, 17F

02/20 13:58, 6年前 , 18F
足夠的抽象化, 其他封裝什麼的都是在這個前提下去作
02/20 13:58, 18F

02/20 13:59, 6年前 , 19F
的, 方法各異. 簡單的例子可以看 fopen/fclose 系列
02/20 13:59, 19F

02/20 13:59, 6年前 , 20F
的擋案操作
02/20 13:59, 20F

02/20 14:02, 6年前 , 21F

02/20 14:56, 6年前 , 22F
Stroustrup 博士曾經有類似的困擾,他最後做了新語言
02/20 14:56, 22F

02/20 14:57, 6年前 , 23F
要不要考慮直接用他做的語言,還蠻多人用的
02/20 14:57, 23F

02/20 14:59, 6年前 , 24F
認真回,把結構當 this 指標,永遠擺在函式第一個參數
02/20 14:59, 24F

02/20 17:50, 6年前 , 25F
所以才有 c++, 其他人寫的也是這樣, 不會有更好的寫法了
02/20 17:50, 25F

02/20 17:53, 6年前 , 26F
你的 open 還沒有把 door * 傳進去
02/20 17:53, 26F

02/20 17:53, 6年前 , 27F
加上後, 會更冗長
02/20 17:53, 27F
謝謝各位的建議,我收穫良多,不過需要一些時間思考跟查資料,所以沒針對各位提供 的方案即時回覆。 有一點要澄清一下,雖然我的OOP不是學得很深,但是只要情況允許C++絕對是我的首選。 只是因為程式運行的平台大多是MCU/MPU/DPS這類產品,大部分的平台開發環境只提供 C編譯器,或是更多的場合是在維護或擴增老舊的C code專案功能,才會出現這種用C 去寫這類結構的情境。 ※ 編輯: icetofux (111.250.44.253), 02/20/2019 21:48:07

02/20 23:46, 6年前 , 28F
網路上找 C 語言 物件導向 有一些文章會展示手法
02/20 23:46, 28F

02/20 23:47, 6年前 , 29F
本來就不是語言內建的東西,用一些概念去寫得像 OO
02/20 23:47, 29F
文章代碼(AID): #1SR1pTWJ (C_and_CPP)