[問題] Opaque pointer的應用

看板C_and_CPP (C/C++)作者 (brotherD)時間7年前 (2018/06/29 11:12), 7年前編輯推噓4(4025)
留言29則, 5人參與, 7年前最新討論串1/1
website: https://en.wikipedia.org/wiki/Opaque_pointer#C 上網查了一下,opaque pointer主要是用來hide implementation,也就是作了一個encap- sulation的動作。 看了一下wiki給的C example,有幾個問題想請教各位 在例題裡,作者把structure definition放在obj.c,且include obj.h,並且在obj.h裡宣 告了 struct obj Q1: 第一次看到struct obj;這種用法,這種用法是告訴compiler我在別的file裡有define struct obj這個data type嗎? 如果是的話,那應該要 + extern吧? 為什麼不加extern也可以? Q2: 剛剛翻了textbook(C how to program),作者說: struct obj{ int id; }; 這個行為叫"define"一個structure且不reserve any space in memory(page 384)。 這個跟我心中認為的define有點出入,不reserve memory的話不是應該叫declare嗎? 還是對於struct與對於variable來說,define與declare的定義不一樣? Q3: 我原本習慣的作法是直接把 struct obj{ int id; }; 這個definition放在obj.h。並不像作者,把它放在.c檔且在.h裡面多declare一個 struct obj。 我想這就是作者所謂的hide implementation。也就是說,struct裡面的member就是 implementation囉? 我認知的implementation是指"實作",也就是function裡的snippet。 所以struct裡面的member也算是implementation嗎?還是在特定的context裡才算數? 謝謝撥冗查看~ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.216.85.243 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1530241960.A.A2B.html

06/29 11:32, 7年前 , 1F
Q1: extern是指定linkage用的
06/29 11:32, 1F

06/29 11:32, 7年前 , 2F
struct沒有linkage所以不能(也不需要)加extern
06/29 11:32, 2F
不好意思,請問這句是什麼意思?

06/29 11:33, 7年前 , 3F
Q2:struct的define跟函數的比較像 有body就是define
06/29 11:33, 3F

06/29 11:34, 7年前 , 4F
Q3:我覺得看context, 各自表述 XD
06/29 11:34, 4F

06/29 12:39, 7年前 , 5F
因為他的struct沒有打算讓你看到 這就是他這樣寫的目的
06/29 12:39, 5F

06/29 12:41, 7年前 , 6F
留那行宣告只是因為他開給你的函式要用而已
06/29 12:41, 6F
我剛剛用gcc試了一下,就算沒加struct obj;這行宣告,只宣告 void obj_setid(struct obj *, int); compiler還是給過。我認為就算沒加struct obj; 對於obj_setid這個function來說,struct obj *本身就是一個declare了,並不需要在前 面多加struct obj;這行宣告

06/29 12:48, 7年前 , 7F
defination就是要有明確的定義 變數是實際執行時的資料
06/29 12:48, 7F

06/29 12:49, 7年前 , 8F
所以它的"明確定義"必須要有存放變數的位置
06/29 12:49, 8F

06/29 12:51, 7年前 , 9F
struct則是"切割記憶體與看待切割區塊的方式"
06/29 12:51, 9F

06/29 13:37, 7年前 , 10F
C 的 type 只是編譯期資訊,不會被編譯到 object file
06/29 13:37, 10F

06/29 13:38, 7年前 , 11F
所以當然不會產生任何在執行期佔據記憶體的東西。
06/29 13:38, 11F

06/29 13:39, 7年前 , 12F
然後語言本身要求識別字 (變數、函式名等) 使用前要宣告
06/29 13:39, 12F

06/29 13:40, 7年前 , 13F
,也就是要告訴編譯器那個識別字是什麼東西。
06/29 13:40, 13F

06/29 13:40, 7年前 , 14F
struct obj; 就是告訴編譯器 obj 是一個 strcut type,
06/29 13:40, 14F

06/29 13:41, 7年前 , 15F
但是細節未知,在只有使用到 obj *,不需要存取 members
06/29 13:41, 15F

06/29 13:41, 7年前 , 16F
或者知道配置一個 obj instance 要多大空間的狀況下,
06/29 13:41, 16F

06/29 13:42, 7年前 , 17F
編譯器是不用知道整個 type definition 的。
06/29 13:42, 17F

06/29 13:43, 7年前 , 18F
識別字要宣告的理由也只是方便 parser 做語法語意檢查。
06/29 13:43, 18F

06/29 16:12, 7年前 , 19F
這很常見的手法,如果不想暴露 struct 細節就這樣寫
06/29 16:12, 19F
我發現就算沒宣告struct obj;這行,程式也編譯的過。 ideone: https://ideone.com/VbUs6R ※ 編輯: zzss2003 (60.251.49.183), 06/29/2018 17:52:41 ※ 編輯: zzss2003 (60.251.49.183), 06/29/2018 17:53:30

06/29 18:53, 7年前 , 20F

06/29 18:54, 7年前 , 21F
勾選 Show compiler warnings 看看.
06/29 18:54, 21F

06/29 20:38, 7年前 , 22F
那是運氣好,該寫還是要寫
06/29 20:38, 22F

06/29 20:42, 7年前 , 23F
可能沒實際呼叫也有差,沒詳細研究...
06/29 20:42, 23F

06/29 21:08, 7年前 , 24F
你是想問為什麼struct沒有linkage嗎
06/29 21:08, 24F

06/29 21:09, 7年前 , 25F
就tinlans回的第一句話那樣
06/29 21:09, 25F

06/30 02:39, 7年前 , 26F
C 規定 struct type 一定要用 struct 開頭,所以你省略的
06/30 02:39, 26F

06/30 02:39, 7年前 , 27F
話,編譯器還是可以正確解析,不過勸你還是養成習慣。
06/30 02:39, 27F

06/30 02:46, 7年前 , 28F
實務上因為這樣寫太冗長,大家會用 typedef 變成免寫
06/30 02:46, 28F

06/30 02:46, 7年前 , 29F
struct,這種時候你就還是得先宣告。
06/30 02:46, 29F
文章代碼(AID): #1RDQEeeh (C_and_CPP)
文章代碼(AID): #1RDQEeeh (C_and_CPP)