Re: [問題] inline和.h寫定義

看板C_and_CPP作者 (我要加入劍道社!)時間13年前 (2010/09/15 02:41), 編輯推噓5(506)
留言11則, 7人參與, 最新討論串2/3 (看更多)
※ 引述《QQ29 (我愛阿蓉)》之銘言: : 請教一個問題... : 之前版上看到 : "寫在.h 定義一定是inline"... : 但是我爬文後也找不到相關能佐證的文章... : 請問這正確嗎?? : 如果自己寫inline這修飾字 也只是"建議" inline : 如果定義寫在.h "一定"是inline嗎? 我想你是誤解了這句話 他的意思是說 如果你要把 function 的定義寫在 .h 中 那你一定要把他標上 inline 否則當這個 .h 檔一旦被多個 .cpp 引用時 連結時會造成 multiply defined symbol 的錯誤 但這樣講其實有點倒因為果 正確的順序應該是 1. 你希望某個很短的 function 能夠 inline 以增加效率 2. 因為 inline 意味呼叫端一定要知道 function 的內容 所以你必需把定義寫在 .h 中 也就是說 inline 這個關鍵字的目的是讓呼叫 function 可以更加快速 而不是去避免 linker error : 假如我class一坨private data..... : 大家都會針對每個private data 寫一份get and set function : 所以說有x個private data 就該有 2*x個function? : 感覺這樣好累 但是不是好的設計一定要這樣寫?? 剛好相反 針對全部的 data member 都做 getter/setter 通常是很爛的設計 當你在設計一個 class 時 你應該先去思考這個 class 會有什麼行為,使用者要怎麼操作它 而不是這個 class 有什麼 data member 比如說 你現在想寫一個秀圖物件 可能你現在腦中馬上想到的 是這個「秀圖物件」必需要去開檔案 所以要有一個 ifstream 的成員 還要把檔案中的資料畫到一塊畫布上 所以要有一塊 memory buffer 來當畫布 請先拋開這些想法 因為這是實作層次的問題 並不是說它不重要 而是你應該先思考你要怎麼讓別人用這個物件 比如說,我希望別人是這樣使用我的 class: 1. 產生物件後,我給他一個檔名,他可以把檔案讀進自己的 buffer 中 2. 我再給他一個 Win32 HDC,可以讓他把 buffer 中的資料畫到視窗上 (其實我也不太懂 Win32 API 啦,先假設這樣好了) 那這個 class 大概會長這樣: class ImageViewer { public: ImageViewer(); ~ImageViewer(); void load(const char* filename); void display(HDC hdc); private: ifstream _input; char* _buffer; }; 你覺得有必要提供 _input 和 _buffer 的 getter/setter 嗎? 應該不用吧 讓使用者去任意存取他們反而會造成你的困擾,對吧 甚至你不想用 ifstream 而想要用 C 的 FILE* 或是這個物件提供網路功能 可以直接把網址當作檔名傳進去 (所以你可能還需要一個 socket handle) 這些都是實作層次上的問題 使用 ImageViewer 的人不需要知道你是怎麼讀檔的 他只要知道 load 與 display 怎麼用就好了 這才是物件導向中封裝的基本意義 並不是把原本的 struct 加上 getter/setter 就叫封裝了 : 至於這種小function 都寫inline修飾 或直接寫在.h的話 : 不就違反 : .h不要寫定義的精神嗎??? 我前面有說明為什麼 .h 不要寫定義 (會產生 multiple definition) 以及為什麼 inline function 要把定義寫在 .h 的原因 (為了讓呼叫端能展開) compiler 在遇到 inline 關鍵字時 會對該 function 進行標示 讓 linker 做特殊處理以避免 multiple definition 的問題 所以 inline function 把定義寫在 .h 是不會有 linker error 的 : 如果"定義寫在.h一定inline" 成立 : 我把定義寫在.h + lib 的話 : 給對方header file他不就看的出來我一些定義 雖說這些function都是簡單get set... : 我該如何在.h不要寫定義 和 inline做取捨呢? : ps. 看教學都是寫 宣告 和 定義 都要寫上inline在前面 如果一邊不寫會怎麼取捨呢? : http://www.greenend.org.uk/rjk/2003/03/inline.html : 這網頁有提到static inline 但光看他描述實在不懂 且為啥他沒寫inline這字眼呢? 這是 C99 的 但因為我想睡了 決定明天再看 : 我在想 之前在學校都有講概念說 class封裝 可以達到資料 隱藏阿之類的 : 我現在突然無法理解他的涵義 : 我給他.h 他把我private:這字眼全刪掉 改成public: 那不就可以任憑他亂搞嘛? 我很久以前寫過 private 是用來防止過失殺人 而不是防止蓄意謀殺 : 我那些get set形同虛設 但如果你全部的 data member 都是 getter/setter 那 private 也的確形同虛設就是了 : 如果是 針對 code實作不想被別人看到要隱藏 編成lib.... : 那也不用針對class來講這觀念..... : 但就算編程lib .h一坨private他還是可以直接改成public 在自己來亂搞 : 這觀念在這邊請教一下...... : 以上 請教各位 thx~ 該怎麼說呢 如果你一邊拿著 effective/exceptional c++ 一邊寫大程式 應該就會愈來愈了解為什麼物件導向是這樣設計 因為少了這些你就很容易拿槍射到自己的腳 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.168.80.218

09/15 02:54, , 1F
推認真~ ^_^
09/15 02:54, 1F

09/15 03:13, , 2F
規格書 7.1.3.4 An inline function shall be defined
09/15 03:13, 2F

09/15 03:14, , 3F
in every translation unit in which it is used and
09/15 03:14, 3F

09/15 03:15, , 4F
shall have exactly the same definition in every c-
09/15 03:15, 4F

09/15 03:16, , 5F
ase 打錯是 7.1.2.4
09/15 03:16, 5F

09/15 11:00, , 6F
好文給推
09/15 11:00, 6F

09/15 11:32, , 7F
好文推
09/15 11:32, 7F

09/15 12:12, , 8F
上下兩篇都是不錯的文章!
09/15 12:12, 8F

09/15 17:14, , 9F
好文給個推
09/15 17:14, 9F

09/15 21:22, , 10F
push~~
09/15 21:22, 10F

08/31 14:25, , 11F
08/31 14:25, 11F
文章代碼(AID): #1CZy70s8 (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1CZy70s8 (C_and_CPP)