C++ 中的三法則與五法則?


三法則是在使用 C++ 時的一條經驗法則。這是一種良好的實踐規則,它指出如果你的類需要以下任何一個:

  • a. 複製建構函式,
  • b. 賦值運算子,
  • c. 解構函式,

顯式定義,那麼它很可能需要這三個中的所有。

為什麼是這樣?因為,如果你的類需要上述任何一個,它就是在管理動態分配的資源,並且很可能需要其他兩個來成功實現這一點。例如,如果你需要一個賦值運算子,你將建立正在透過引用複製的物件的副本,從而分配資源。你需要複製建構函式進行復制,並需要解構函式釋放這些資源。

五法則由於 C++11 中引入了移動語義,它是三法則的擴充套件。五法則也應用於 C++ 中的資源管理。此規則可以消除 C++ 程式碼中的記憶體洩漏和其他問題。五法則指出,如果你必須編寫以下函式之一,那麼你必須對所有這些函式制定策略。如果我們有一個物件 Foo,那麼我們可以有一個 FooManager 來處理資源 Foo。在實現 FooManager 時,你很可能需要實現以下所有函式:

  • 解構函式 - 當此管理器超出範圍時,它應該釋放它正在管理的所有資源。

  • 賦值運算子 - 如果你不提供一個,編譯器會建立一個預設的賦值運算子。預設賦值操作是一個逐成員複製函式,執行淺複製而不是深複製。這可能會導致記憶體洩漏、錯誤賦值等問題。

  • 複製建構函式 - 編譯器提供的複製建構函式會逐成員複製所有 FooManager 屬性。這會帶來與賦值運算子相同的問題。

  • 移動建構函式 - 複製物件可能代價高昂,因為它涉及建立、複製然後銷燬臨時物件。C++11 引入了右值引用的概念。右值引用可以顯式繫結到右值。右值是未命名的物件。換句話說,就是臨時物件。此右值引用可用於建構函式中,以建立對傳遞給它的右值的引用。

  • 移動建構函式 - 複製物件可能代價高昂,因為它涉及建立、複製然後銷燬臨時物件。C++11 引入了右值引用的概念。右值引用可以顯式繫結到右值。右值是未命名的物件。換句話說,就是臨時物件。此右值引用可用於建構函式中,以建立對傳遞給它的右值的引用。

  • 移動賦值運算子 - 一次只擁有一個資源很有用。此資源的所有權可以從一個管理器轉移到另一個管理器。在這種情況下,你可以提供一個移動賦值運算子。

這是一個瞭解五法則的好資源 - https://www.feabhas.com/sites/default/files/2016-06/Rule%20of%20the%20Big%20Five.pdf.

更新於: 2020 年 6 月 24 日

440 次瀏覽

啟動你的 職業生涯

透過完成課程獲得認證

開始學習
廣告