三法則

三法則

三法則(Rule of Three)在C++里,它是一個以設計的基本原則而制定的定律。它的要求是,假如類有明顯定義下列其中一個成員函式,那么程式設計師必須寫入其他兩個成員函式到類內,也就是說下列三個成員函式缺一不可:析構函式複製構造函式賦值運算符。上述三個函式是特別的成員函式,假如程式設計師沒有自行定義或宣告這三個函式,編譯器會自動地創建他們並且編譯到應用程式內。然而,如果程式設計師僅定義其中一個,其餘兩個函式仍然會由編譯器自動產生,這種混雜的情況非常容易產生程式設計師難以預期的錯誤。三法則的存在,正是提醒程式設計師避免那樣的陷阱。

基本介紹

  • 中文名:三法則
  • 外文名:Rule of Three
  • 學科:計算機語言
  • 定義:以設計的基本原則而制定的定律
  • 組成:析構函式、複製構造函式
  • 提出者:馬歇爾·克來恩
簡介,組成,代碼示例,

簡介

三法則這個專有名詞是由馬歇爾·克來恩於1991年創立的,假設類有用到RAII,可以不必定義析構函式。 因為隱式生成的構造函式與賦值運算符可以很容易地複製類內所有的數據成員,當數據成員是指針類型時,指針地址會隨著類而跟著被複製。要注意的是,直接地複製指針地址是一項非常危險的動作,所以只要類有封裝指針類型的數據結構,或是類有封裝外部引用的數據成員,例如指針類型的數據成員,程式設計師應該為此而定義顯式的複製構造函式與賦值運算符。AII全稱為Resource Acquisition Is Initialization,它是在一些面向對象語言中的一種慣用法。RAII源於C++,在Java,C#,D,Ada,Vala和Rust中也有套用。1984-1989年期間,比雅尼·史特勞斯特魯普和安德魯·柯尼希在設計C++異常時,為解決資源管理時的異常安全性而使用了該用法,後來比雅尼·史特勞斯特魯普將其稱為RAII。RAII要求,資源的有效期與持有資源的對象的生命期嚴格綁定,即由對象的構造函式完成資源的分配(獲取),同時由析構函式完成資源的釋放。在這種要求下,只要對象能正確地析構,就不會出現資源泄露問題。

組成

析構函式
析構函式(Destructordtor)在面向對象程式設計里是一個方法,當對象的生命周期結束時,它會自動地被調用運行。它最主要的目的在於,清空並釋放對象先前創建或是占用的存儲器資源。析構函式的整體使用概念關鍵在於RAII。一個具備垃圾回收機制的程式語言,無法確保析構函式是否會被運行,通常這類的程式語言不屬於RAII的範圍內。這類的程式語言,只要經由某個適當的函式,通常會調用Dispose()函式,做調用的動作,那么它一定會從現有資源釋放對象。與使用垃圾回收機制的Finalize()相比,建議使用析構函式是釋放資源的適當做法。
複製構造函式
複製構造函式(Copy constructor)是C++程式語言中的一種特別的構造函式,習慣上用來創建一個全新的對象,這個全新的對象相當於已存在對象的副本。這個構造函式只有一個參數(引數):就是用來賦值對象的引用(常用const修飾)。構造函式也可以有更多的參數,但除了最左第一個參數是該類的引用類型外,其它參數必須有默認值。
類的賦值構造函式原型通常如下:Class_name(const Class_name & src);
一般來說,假如程式設計師沒有自行編寫賦值構造函式,那么編譯器會自動地替每一個類創建一個賦值構造函式;相反地,程式設計師有自行編寫賦值構造函式,那么編譯器就不會創建它。當對象包括指針或是不可分享的引用時,程式設計師編寫顯式的賦值構造函式是有其必要性的,例如處理檔案的部分,除了賦值構造函式之外,應該還要再編寫析構函式與賦值運算符的部分,也就是三法則。
賦值運算符
在C++程式語言里,賦值運算符(assignment operator)是用等號 = 符號。就像其他的C++運算符一樣,它可以作為重載。賦值賦值運算符是一個特別的賦值運算符,通常是用來把已存在的對象指定給其他相同類別的對象。它是一個特別的成員函式,如果程式設計師沒有定義這個成員函式,那么編譯器會自動地產生這個成員函式。編譯器產生的代碼是以單一成員進行對象賦值的動作。賦值賦值運算符,這個成員函式與賦值構造函式的相異點在於,它一定會清除目標對象的數據成員(以及確實掌控自我設值的動作),而賦值構造函式不會初始化類別的數據成員。

代碼示例

#ifndef _HEADER_H_ #define _HEADER_H_ // //判斷是否為微軟編譯器#ifndef _MSC_VER #undef NULL #define NULL 0 #endif // #include  <iostream> #include  <limits> // using  std :: cin ; using  std :: cout ; using  std :: endl ; // //類別:方塊class  CCube { public :     //建構子    CCube ();     //含有參數的建構子    CCube ( double  length ,  double width ,  double  height );     //三法則:解構子    ~ CCube ();     //三法則:複製建構子    CCube ( const  CCube  & sample );     //三法則:設定運運算元    CCube &  operator = ( const  CCube  & sample );     //設定長寬高     void  setLength ( double  length );      void  setWidth ( double  width );      void  setHeight ( double  height );     //取得長寬高    double  getLength ()  const ;     double  getWidth ()  const ;     double  getHeight ()  const ;     //計算體積    double  getVolume ()  const ; protected : private :     //長寬高    double  m_Length ;     double  m_Width ;     double  m_Height ; }; // void  PAUSE ( void ); // #endif

相關詞條

熱門詞條

聯絡我們