Herb Sutter談現代C 本質

2021-09-16 18:16:23 字數 3368 閱讀 9771

在cppcon 2014上,herb sutter做了乙個演講,展示了現代c++程式設計的基本慣用法。下面是乙個簡短的概要。

\u0026#xd;\n\u0026#xd;\n

herb承認儘管c++不是對每個程式設計師都是複雜的,但它是乙個複雜的語言。herb建議這樣來看待c++,只有極少一部分程式設計師應該關注語言的最晦澀難懂的方面,比如當處理低層或庫**時,而其他人只需要通過預設的方式使用它,並讓它能工作就可以了。

\u0026#xd;\n\u0026#xd;\n

第乙個例子是盡量多使用range-for迴圈。事實上,你也可以這樣寫:

\u0026#xd;\n\u0026#xd;\n

\u0026#xd;\nfor (auto i = begin(c); i != end(c); ++i)
\u0026#xd;\n\u0026#xd;\n

在現代c++中,乙個更容易的寫法是這樣的:

\u0026#xd;\n\u0026#xd;\n

\u0026#xd;\nfor (auto\u0026amp; e : c)
\u0026#xd;\n\u0026#xd;\n

這種寫法也提供了更好的可讀性。

\u0026#xd;\n\u0026#xd;\n\u0026#xd;\n\u0026#xd;\n

herb的另乙個強烈的建議是除非被封裝在低層資料結構的實現內部,否則不要使用有所有權的指標(owning pointer)new或者delete。乙個更好的選擇是unique_ptr,或者當你知道你需要共享這個物件的時候,使用shared_ptr。因此,你可以很容易地寫成:

\u0026#xd;\n\u0026#xd;\n

\u0026#xd;\nauto p = make_unique\u0026lt;widget\u0026gt;();\u0026#xd;\nauto q = make_shared\u0026lt;widget\u0026gt;();
\u0026#xd;\n\u0026#xd;\n

通過使用make_unique和make_shared,你甚至不用擔心delete的問題。

\u0026#xd;\n\u0026#xd;\n

不管怎樣,無所有權的指標(non-owning pointer)和引用仍然是乙個很好的資源,並且使用它們最好的場合是傳遞引數給函式。herb認為使用任何種類的引用計數變數來傳遞引數是一種真正的反模式。這只可能導致效能問題,只有當你想把封裝物件的所有權轉移出去的時候才應該用它。

\u0026#xd;\n\u0026#xd;\n\u0026#xd;\n\u0026#xd;\n

據herb的說法,auto關鍵字是現代c++最大的特性之一。auto能夠用來推斷型別,但是也可以用來指定型別並且一直代表那種型別。考慮下面的語句:

\u0026#xd;\n\u0026#xd;\n

\u0026#xd;\nauto i = v.begin();
\u0026#xd;\n\u0026#xd;\n

這將正確地推斷出所使用的型別。相比於下面的語句,這更簡單並且不需要太多思考就能寫出來。

\u0026#xd;\n\u0026#xd;\n

\u0026#xd;\nvector::const_iterator i = v.begin();
\u0026#xd;\n\u0026#xd;\n

上面的語句專門需要思考使用const_iterator。

\u0026#xd;\n\u0026#xd;\n

正確性是auto的最大好處,但是它也有其他方面的好處:

\u0026#xd;\n\u0026#xd;\n

· 可維護性:它使得**自動適應變化,比如,函式的返回值。

\u0026#xd;\n\u0026#xd;\n

· 效能:作為正確型別推斷的必然結果,auto能避免無意中產生臨時物件,比如,初始化乙個物件的時候。

\u0026#xd;\n\u0026#xd;\n

· 可用性:在特殊的上下文中,比如,auto是lambda函式的乙個促成因素。

\u0026#xd;\n\u0026#xd;\n

· 打字方便:它可以少敲幾下鍵盤。

\u0026#xd;\n\u0026#xd;\n

然而,有些情況下你不能使用auto,換句話說,當你處理c陣列或者不可移動的型別或者移動起來開銷太大的型別,比如:

\u0026#xd;\n\u0026#xd;\n

\u0026#xd;\nauto lock = lock_guard\u0026lt;mutext\u0026gt; ;  // 錯誤:不可移動\u0026#xd;\nauto ai = atomic\u0026lt;int\u0026gt;{}; // 錯誤:不可移動\u0026#xd;\nauto a = array\u0026lt;int,50\u0026gt;{}; // 正確,但開銷太大
\u0026#xd;\n\u0026#xd;\n\u0026#xd;\n\u0026#xd;\n

herb演講的很大一部分都專注在討論引數傳遞。他的要點是,c++98預設用法在現代c++中還繼續有效,並且代表了乙個很好的起點,而右值優化帶來更多的可能性。下面這個例子說明我們總是應該怎麼做:

\u0026#xd;\n\u0026#xd;\n

\u0026#xd;\nclass employee     // 標準 c++98 的習慣\u0026#xd;\n    void set_name(std::string\u0026amp;\u0026amp; name) noexcept     // 右值優化\u0026#xd;\n};
\u0026#xd;\n\u0026#xd;\n

另一方面,herb建議值傳遞主要用在建構函式中。在其他場合,當你按值傳遞乙個命名引數(也即,非臨時物件),並且允許右值優化,會引起很大的效能影響,因為該引數會被拷貝。

\u0026#xd;\n\u0026#xd;\n\u0026#xd;\n\u0026#xd;\n

herb最後乙個建議是關於使用元組來返回多個值:

\u0026#xd;\n\u0026#xd;\n

\u0026#xd;\ntie(iter, success) = myset.insert(\"hello\");\u0026#xd;\nif (success) do_something_with(iter);
\u0026#xd;\n\u0026#xd;\n

除了強調預設用法和慣用法的重要性,herb也建議避免過度思考從而導致解決方案過度混淆。總之,他的秘訣是首先與語言提供的最基礎的用法保持一致,然後通過實測,找到一些有希望改進的領域,嘗試一些不一樣的手段來改進效能。

\u0026#xd;\n\u0026#xd;\n

檢視英文原文:herb sutter on modern c++ essentials

\u0026#xd;\n\u0026#xd;\n

感謝郭蕾對本文的審校。

\u0026#xd;\n\u0026#xd;\n

也談「以人為本」的測試

看了一篇關於軟測的文章,文中說到軟測的三個階段,最後乙個階段是說以人為本的測試,筆者略有感觸,所以也來談談 以人為本 的測試。剛進公司的時候,筆者也非常痴迷於測試流程,cmmi之類,覺得流程框架之類很偉大,指引並驅動著我們的工作,每一項工作都應該有輸入輸出,並且符合標準,基線化猶如心中女神一般,充滿...

《c語言程式設計 現代方法》

我最開始接觸的c語言書籍是,譚浩強的c語言教材。在 資料結構 中,學會了使用指標。後來,單獨花時間克服了字元的處理。工欲善其事,必先利其器。我在本科暫時的三個目標是 c c 作業系統,網路。暑假看了 作業系統 真象還原 作業系統的知識,暫時夠我使用了。歡迎在這個倉庫上,建立分支,留下本書好的 c語言...

我的筆記本選購經驗談

以下是個人的一點nb選購經驗,希望能對大家有所幫助 2.找到幾個不同品牌相似配置 或是相同品牌類似配置 的nb後,下一步就是仔細進行比對啦,看看這幾個nb的具體差別在 哪些更適合你,某些配置有明顯缺陷或是瓶頸的就可以剔掉了 對於注重外觀的mm,機器外型開始起作用啦.多少小黑就這樣慘遭淘汰 這一步的目...