看板 Soft_Job 關於我們 聯絡資訊
身為一個 c++ 愛好者(?) 也來幫 c++ 說說話吧 其實我得說我真的不是完全懂了 c++。我相信多數人在看了神人的 code 也會有跟我 一樣的想法。如果有人覺得我寫的哪裡不對也請不吝指正。 對我來說我覺得 c++ 的重點就是 scope,type 還有一部分承襲自 oop 的特性 我寫過 java 和 py 等等其他由 platform 提供 gc 的語言 他們很好沒錯,你不用擔心記憶體釋放的問題。而通常 c 會用 goto 走到函數尾巴, 而 c++ 可以讓你透過 stack helper 來管理資源,讓你只在乎他的宣告。 透過 destructor 來自動釋放。這是 c++ 的特色,比起 mark and sweep 家族的方法 他少了 pause,而且可以精確的知道物件何時被釋放,而且由於你知道時間點 所以你可以做除了記憶體釋放以外的事情,比方說,關 fd,下 log.... 當然如果 ownership 不明確,你就會需要 reference counting,就有那種 cycle 和 thread safe 的問題,這時候你可以透過很更嚴格的紀律去要求何時應該要用 weak 或是何時應該要用比較昂貴的 thread-safe counter。 或是你也可以直接用 gc library,c++ 不在 standard library 裡面做 gc,但他留給 你自己做。 但是資源管理的同時,你必須知道什麼東西是在 stack 裡面,他大概長什麼樣子, 他被銷毀的時候誰會被呼叫,這意思也就是說,compiler 到底在你的 code 裡面大概 幫你幹了什麼事情,在你這個 frame 結束前他有幫你做什麼。所以 c++ 管理資源的方 法在於你對於每種方法的認知和他的代價。 說到型別 c++ 有個很有趣的型別系統。型別讓你在 compile time 的時候指導 compiler 走進正確的路,或者是生出正確的 code。甚至在 compile time 做計算。 你可以提供一段程式碼,它用起來就像真正的函數一樣,可是他可以在 compile time 的時候透過 compiler 已經認知的型別插一段 inline 在你的 code 裡面。因為 inline,所以沒有 locality 和 function call overhead,可是你用起來就像是 function。或者是新的 rvalue ref,你可以告訴 compiler 某個物件在某種狀態的時候 用這個 function,在 function 中你可以知道這個物件已經要走到盡頭,所以你可以不 用擔心之後還會被別人用,放膽地把它生吞活剝。 用 template 基本上就是用空間換速度,當然空間大到一定的程度也會影響到速度, 所以用的時候必須有點 sense 到底這樣下去會發生什麼事情。亂用 object code 就會 變大。compile time 可以幫你做好 template 計算,你可以準備特化樣板讓 compiler 去用,只要設定得當你可以透過一個很 general 的樣板生出針對不同型別具有特殊 意義的 code。 最後講到 oop,我相信講 oop 大家都不會推 c++,老實說我也沒有寫過真正的 oop, 我認知的 oop 大概就像 java 裡面那種有 dynamic cast 然後所有物件都是 object 的 oop。c++ 不是這樣,但他的 oop 非常好理解,前提是你要對 function compile 以後長什麼樣子有點概念。什麼東西大概會變成什麼符號,什麼東西會跟著特定物件 走。然後指向 vtable 對於一個物件到底是什麼意義。怎麼樣可以讓物件在 run time 的時候找到一個 function,這跟 c 的 function ptr 有一點異曲同工之妙,實際上 c 也可以用 function ptr 來建造 virtual function。 我想說我對於 c++ 最愛的點就是,所有東西都很明確,到底我這樣做底下發生了 什麼事情。一個 vector push back 到底做了什麼事情,我大概心裡有底。攤銷的複雜 度,什麼東西會改變...等等的。然後同時因為 compile time 做完很多的事情,他的執 行速度快,只要你寫得好。還有 compiler 替你檢查型態和語法,讓很多問題不需 要等到 automation 的時候才發現。 所以我會說 c++ 是個很難的語言,因為你要很清楚你的每一步踩在什麼上面,但是他就 像寶庫一樣你可以一直挖。而且我相信用到極端的狀況 py 和 java 不會簡單到哪去, 只是學習曲線和信仰問題。 ※ 引述《descent (「雄辯是銀,沉默是金」)》之銘言: : c++ 太可憐了, 想為 c++ 說點話, c 之所以難學, 其中有個指標的難題, c++ 可以在某 : 種程度上減低這樣的困難。 : int getaddrinfo(const char *node, const char *service, : const struct addrinfo *hints, : struct addrinfo **res); : 呼叫 getaddrinfo 之後, 還得記得要 freeaddrinfo(result), 而 res 本身又是個複雜 : 的 linked list 資料結構, 有興趣可以參考 man page 的用法, 雖然難不倒你, 但用起 : 來實在太複雜。 : 要是用 c++, 就可以使用 std::vector 來對付這樣的資料結構, 無需操作指標, 又保有 : 高效率。 : vector<XXX> res : getaddrinfo(..., res); : for (int i=0 ; i < res.size() ; ++i) : { : } : 不需要記得去 free 記憶體, 也不用使用那令人害怕的兩顆星操作。 : 而 c++ 也提供了 std::string, 光是這個和 std::vector, std::list, 就足夠降低寫 : c 程式的門檻, 不用辛苦的注意 \0 到底有沒加上, 字串 size 是不是少了一, 更不用擔 : 心老是搞不清楚 : char str[] = "abc"; : char *str="abc"; : static char *str="abc"; : 這些奇怪的差異, 我還沒提到如果 function 要傳入, 或是傳回字串時的麻煩事。 : 這些都減少了很多初學者操作指標的困擾, Joel 說過, 一個語言好用是因為你不用自己 : 管理記憶體, c++ standard library 提供了不少的幫助, 這些都比學習 c 來得容易。 : 我第一個自學的語言是 x86 組合語言, 遇到重重困難, 一事無成, 太高估我自己了, 若 : 一開始改學 c/c++, 應該略有小成。 : 從我改學 c++ 之後, 大多是她陪伴著我, c 也是靠著學 c++ 時, 順便接觸到的, 果然要 : 操作指標難度會整個提升不少。 : 那你說 template, oo, lambda, c++11, c++14 那些東西呢? : 管他的! 你需要多學習那些才能寫出程式嗎? : 雖然工作都是以 c/c++ 為主, 不過薪水沒有特別高。 : ※ 引述《NewSpec (新規格)》之銘言: : : 這個問題我老早就想請教各位版大了 : : 並不是為了嗆前面那個問題= ="" : : 雖然說有人覺得學C/C++沒必要 : : 但事實上就是某幾個browser公司依舊缺C/C++工程師 : : 做big data的一樣缺C/C++ infra工程師 : : 前陣子有人跟我說有個能讓我現在package +50%的機會 : : 一樣是要Linux network programming : : 但我他媽的就是一個不值錢的java/python/scala後端 : : 事到如今我已經再也受不了了 : : 能力也不是比別人弱,但一開始路就走錯了又能怎樣 : : 所以想請問各位學習C/C++並能使之成為應職技能要怎樣能比較快達到? : : 我已經在物色github project想contribute了, : : 但不知道別人吃不吃這套... QQ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.136.74.202 ※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1423620845.A.274.html
jay101: 推 02/11 10:26
teemocogs: 推 02/11 10:54
leolarrel: 最後兩段話看完,我覺得你該用C才對 02/11 11:08
leolarrel: 語言行為明確度不如C,便利性又不如現在各大直譯語言 02/11 11:10
ckvir: c 哪時常用 goto 到函式尾巴?我看linux kernel 幾乎沒goto 02/11 11:33
noonOut: 你說的明確度讓我想到一件事情,我說明確其實是錯的。任 02/11 11:33
noonOut: 何語言都很明確,差別是你多懂他還有他有多少是標準定義 02/11 11:33
noonOut: 的,多少是實作定義的。我覺得我對 c++ 的理解程度讓我可 02/11 11:33
noonOut: 以把許多狀況視為明確,不過也有很多需要看手冊,但我大 02/11 11:34
noonOut: 概有感覺那個標準和實做的分界在哪。 02/11 11:34
leolarrel: ckvir,linux kernel很常用goto 模擬 try...catch 02/11 11:38
leolarrel: 但是數量上,恩,"少"或"多"是很主觀的,所以不便說啥 02/11 11:39
leolarrel: noonOut,我使用的"明確度"是針對你最後兩段話 02/11 11:40
leolarrel: 如果你喜愛C++的原因是因為語言行為你絕得很透明清晰 02/11 11:42
leolarrel: 那麼C反而更符合這個好處 02/11 11:43
james732: C++是一個會覺得越學越不懂的神奇語言啊....XDDDDD 02/11 12:05
noonOut: c 對我來說簡單就是 compiler 提供的協助太少。而 c++ 02/11 12:12
noonOut: 不曉得你說不明確的地方是哪裡,如果是說 STL 蓋住的部 02/11 12:12
noonOut: ,我覺得多數情況下 spec 寫的東西已經夠清楚了。而且 c+ 02/11 12:12
noonOut: + 共用很大一部分的 c 語法,真的有需要我可以用 c 刻出 02/11 12:12
noonOut: 來,再包裝成 c++ 就可以借用 c++ compiler 的功能。 02/11 12:12
leolarrel: 我回文好了,這樣會比較方便打字 02/11 12:36
zb26: 其實PO愛用花柄榔頭,我們也管不著. 02/11 13:28
zb26: 十年過去,非常清楚,C++跟他的複雜技術是一門屠龍術,沒用了 02/11 13:28
uranusjr: 小 bug:Python 的 GC 主軸是 reference counting,雖然 02/11 15:50
uranusjr: 也是有 mark-and-sweep 但大部份時間還是很多 RAII 概念 02/11 15:52
noonOut: 感謝補充 看到這種留言真開心 02/11 16:03
snaketsai: CPython的GIL是個硬傷...這點讓我用得有點無奈(嘆) 02/11 16:21
leolarrel: GIL是個硬傷+1 02/11 16:26
qrtt1: 可以上 py3 或是用 pypy 啊。 02/11 19:48