C++ 中的“三法則”與“五法則”
“三法則”是使用 C++ 時的一條經驗法則。這是一種良好的實踐規則,它指出如果你的類需要以下任何一項:
- a. 複製建構函式,
- b. 賦值運算子,
- c. 解構函式,
被顯式定義,那麼它很可能需要這三者中的所有。
為什麼是這樣?因為如果你的類需要上述任何一項,它就正在管理動態分配的資源,並且很可能需要其他兩項才能成功地實現這一點。例如,如果你需要一個賦值運算子,你將建立當前正在透過引用複製的物件的副本,從而分配資源。你需要複製建構函式來進行復制,以及解構函式來釋放這些資源。
“五法則”是由於 C++11 中引入了移動語義而對“三法則”的擴充套件。“五法則”也應用於 C++ 中的資源管理。此規則可以潛在地消除 C++ 程式碼中的記憶體洩漏和其他問題。“五法則”指出,如果你必須編寫以下函式之一,那麼你必須為所有這些函式制定一個策略。如果我們有一個物件 Foo,那麼我們可以有一個 FooManager 來處理資源 Foo。在實現 FooManager 時,你很可能需要實現以下所有函式:
解構函式 - 當此管理器超出範圍時,它應該釋放它正在管理的所有資源。
賦值運算子 - 如果你不提供一個,編譯器會建立一個預設的賦值運算子。預設的賦值操作是一個逐成員複製函式,它執行淺複製而不是深複製。這可能會導致記憶體洩漏、錯誤賦值等問題。
複製建構函式 - 編譯器提供的複製建構函式會逐成員複製所有 FooManagers 的屬性。這會帶來與賦值運算子相同的問題。
移動建構函式 - 複製物件可能代價高昂,因為它涉及建立、複製然後銷燬臨時物件。C++11 引入了右值引用的概念。右值引用可以顯式繫結到右值。右值是一個未命名的物件,換句話說,就是臨時物件。此右值引用可用於建構函式中,以建立對傳遞給它的右值的引用。
移動建構函式 - 複製物件可能代價高昂,因為它涉及建立、複製然後銷燬臨時物件。C++11 引入了右值引用的概念。右值引用可以顯式繫結到右值。右值是一個未命名的物件,換句話說,就是臨時物件。此右值引用可用於建構函式中,以建立對傳遞給它的右值的引用。
移動賦值運算子 - 一次只擁有一個資源很有用。此資源的所有權可以從一個管理器轉移到另一個管理器。在這種情況下,你可以提供一個移動賦值運算子。
這是一個瞭解“五法則”的絕佳資源 - https://www.feabhas.com/sites/default/files/2016-06/Rule%20of%20the%20Big%20Five.pdf.
資料結構
網路
關係型資料庫管理系統
作業系統
Java
iOS
HTML
CSS
Android
Python
C 程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP