看板 C_and_CPP 關於我們 聯絡資訊
如題 public methods 應該不需要討論了 假設是一個多人合作的專案 你開發的部分很可能之後會換人維護 那麼有必要在 private method 進行參數的 validation 嗎? 我稍微找了一下, 網路上的答案大概有兩類: 1. Using assertion to check in private method 2. Using auto test to insure that the function is not violating your assumptions 大家都認為不該花運算時間在裡面 但人有失蹄馬有亂手 也有可能之後的維護者直接新增 public 介面呼叫 private method 如果是上述的情況似乎 (1), (2) 都無法避免產生問題 不過每個 private method 都檢查參數似乎也有點瘋狂 不知道大家都如何處理此類問題呢? -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 59.120.41.39 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1422176579.A.1A9.html
Ebergies: 目前我是比較傾向或許所有的 function 都該檢查 inputs 01/25 17:04
kwpn: 有時pointer可被reference取代,可以減少檢查. 01/25 17:20
這邊是泛指應該讓程式維持正常的檢查, 就算是 integer 有時也需要檢查~
carylorrk: 我認為不需要,你的例子實作 public member func 的人 01/25 18:10
carylorrk: 有責任自己 check。 01/25 18:10
wuliou: 我我覺得assertion就夠了 01/25 19:23
我也覺得責任應該在實作 public member func 的人 assertion 就是為了希望在開發期就可以發現
PkmX: 還是要check啊 總比程式拿到垃圾input不知道還在亂跑好 01/25 22:47
PkmX: 多餘的測試交給compiler最佳化處理就好 有問題再抓出來看 01/25 22:48
Compiler 可以最佳化到這種程度嗎 XD 另外您的有問題是指? 效率有問題 profiling 再去處理嗎?
PkmX: 是的 01/26 20:46
Killercat: =o= 在C++裡面應該是稱為private class function,BTW 01/27 08:39
哈哈被其它語言荼毒用習慣 method 了 xD
Killercat: 回到正題,我不認為private function需要檢查這個 01/27 08:39
Killercat: 除非這個parameter是從別的地方拿來的,比方說在functi 01/27 08:40
Killercat: n裡面經由別的service拿到值再塞進自己的private 01/27 08:40
Killercat: 我們以前的作法是所謂的邊界防火牆,任何外部值在 01/27 08:41
Killercat: onFetch的時候都要做validation,以這標準來講的話 01/27 08:41
Killercat: public/protected function的parameter跟所有從外部拿 01/27 08:42
Killercat: 值得地方(包括private內部)都會先檢查一次 01/27 08:42
Killercat: 按這標準的話是不會檢查private function param的 01/27 08:42
這幾天我仔細了想了一想, 加上諸位先進的想法, 我整理一下目前我的觀點: 1. 為什麼我們要做參數檢查? 為了防止程式產生預期之外的行為 2. 為什麼我們不在 private function 做參數檢查? 因為 private function 的參數是我們能掌握的, 如同殺手貓說的一樣, 有外部防火牆擋住, 所以 pass 給 private function 的參數應該都是正確的 3. 那麼在 private function 做參數檢查有什麼壞處呢? 既然參數是正確的, 多做檢查只是浪費計算資源, 而且會多寫不必要的程式碼 4. Compiler 有可能幫我們最佳化 private function 的參數檢查嗎? 這部分我試寫了一個簡單的小程式: class A { public: float Sqrt(float a) if (a < 0) return 0; else return _Sqrt(a) private: float _Sqrt(a) if (a < 0) return 0; else return sqrt(a) } int main() { A a; cin >> b; cout << a.Sqrt(b); } 在 g++ 4.6.3 -O 沒開的時候的確會檢查兩次, 而 -O 時則只會檢查一次 因此, 也許很多情況, 在 private fucntion 做參數檢查並不會影響太多的效 能 假想一下, 現在有一群人在開發假設, 同一個 class (不一定誰先誰後, 或同時) 我們規定了傳遞給 private function 的人一定要給予正確的參數, 那麼情況會 變成: A 製作了一個 private function _SetupDev, 用在 public function LoadDev B 現在想要使用 _SetupDev: bool _SetupDev(int SleepPeriod, int MaxJobs, int MinJobs); 那麼, B 該傳什麼參數給 _SetupDev? 我想通常的行為要不 B 跑去問 A, 要不 B 必須要去看 LoadDev 寫了什麼 bool LoadDev(string strFileName) { ... if (1 > SleepPeriod || MinJobs < 0 || MaxJobs < MinJobs) { ReportError; } ... 所以 B 了解了 _SetupDev 的 SleepPeriod 不能小於 1... 而另一個方案, 我們規定, 所有 function 都應該檢查它自己的參數正確性, 情況就變成: if (ENUM_OK != _SetupDev(SleepPeriod, MaxJobs, MinJobs)) { ReportError; } or try { ... _SetupDev(SleepPeriod, MaxJobs, MinJobs); } catch ... B 可以完全的不需要知道 _SetupDev 內部詳細的實作, 也可以避免因粗心造 成的參數誤傳; 另一方面, 我想檢查自己的參數正不正確, 感覺比確認給別 人的參數正不正確來得單純 寫到這邊, 我覺得之所以會有這種想法, 也許是因為以我們這種有可能多人 撰寫同一個 class 或維護的情況, 儘管是 private function, 對合作開發 的人來說也可以當作是一層 interface 了吧 但公司的職員往往來來去去, 也許這種狀況也無法避免就是
carylorrk: function 訊息用 doc 描述,怕開發粗心用 #ifdef DEBUG 01/27 18:30
carylorrk: 如果開發者自己不注意檢查 input,問題會更多。 01/27 18:31
carylorrk: input 指的是任何從外部來的不可控因子。 01/27 18:33
carylorrk: 如果在 private callee 檢查,caller 卻忘記檢查出現漏 01/27 18:37
carylorrk: 洞的機會基本上也很大,而且對 caller 來說也是意外的 01/27 18:38
carylorrk: 錯誤。如果是意料中的例外,又爲何不好好檢查XD? 01/27 18:38
carylorrk: 不過當然不需要不代表不可以,雖然我覺得這樣不代表更 01/27 18:45
carylorrk: defensive 就是了... 01/27 18:45
的確, caller 忘記檢查也是意外的錯誤, 但或許這個意外錯誤呈現的方式可能會不同? 也許是 Error code v.s. SIGSEGV? XD ※ 編輯: Ebergies (59.120.41.39), 01/27/2015 20:30:27