三法則
外觀
此條目可參照英語維基百科相應條目來擴充。 (2022年11月15日) |
三法則(英語:Rule of Three)以及五法則在C++裏,它是一個以設計的基本原則而制定的定律。
規則
[編輯]它的要求是,假如類別有明顯定義下列其中一個成員函數,那麼程式設計師必須寫入其他兩個成員函數到類別內,也就是說下列三個成員函數缺一不可[註 1] [1]。
上述三個函數是特別的成員函數,假如程式設計師沒有自行定義或宣告這三個函數,編譯器會自動地建立他們並且編譯到應用程式內。然而,如果程式設計師僅定義其中一個,其餘兩個函數仍然會由編譯器自動產生,這種混雜的情況非常容易產生程式設計師難以預期的錯誤。三法則的存在,正是提醒程式設計師避免那樣的陷阱。 三法則這個專有名詞是由馬歇爾·克來恩於1991年創立[註 2][2]。
它的修正版本是,假如類別有用到RAII,可以不必定義解構子,也就是所謂的二大定律[註 3][3]。 因為隱性產生的建構子與設定運算子可以很容易地複製類別內所有的資料成員[4],當資料成員是指標型態時,指標地址會隨着類別而跟着被複製[註 4]。要注意的是,直接地複製指標地址是一項非常危險的動作,所以只要類別有封裝指標型態的資料結構,或是類別有封裝外部參照的資料成員,例如指標型態的資料成員,程式設計師應該為此而定義顯性的複製建構子與設定運算子[註 5]。
五法則
[編輯]範例
[編輯]標頭檔 header.h | 主函數 main.cpp |
---|---|
#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
|
#include"header.h"
//
// 判斷是否為微軟編譯器
#ifndef _MSC_VER
int
#else
void
#endif
main(int argc, char* argv[])
{
// 方塊零
CCube cube0(4.3, 5.2, 6.1);
// 第一個方塊
{
cout << "=== No.1 cube ===" << endl;
CCube cube1 = cube0;
cout << "Volume of cube = " << cube1.getVolume() << endl;
}
// 第二個方塊
{
cout << "=== No.2 cube ===" << endl;
CCube cube2;
cube2 = cube0;
cout << "Volume of cube = " << cube2.getVolume() << endl;
}
PAUSE();
return
#ifndef _MSC_VER
EXIT_SUCCESS
#endif
;
}
|
標頭檔實作 header.cpp | |
#include "header.h"
//
void PAUSE(void)
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "press any key to continue...";
cin.get();
}
CCube::CCube()
{
cout << "Constructor: CCube()" << endl;
this->m_Length = 0.0;
this->m_Width = 0.0;
this->m_Height = 0.0;
}
CCube::CCube(double length, double width, double height)
{
cout << "Constructor: CCube(length, width, height)" << endl;
this->m_Length = length;
this->m_Width = width;
this->m_Height = height;
}
CCube::~CCube()
{
cout << "Destructor: ~CCube()" << endl;
this->m_Length = 0.0;
this->m_Width = 0.0;
this->m_Height = 0.0;
}
CCube::CCube(const CCube &sample)
{
cout << "Copy constructor: CCube(const CCube &sample)" << endl;
//
// 保護:禁止設值給自己
if (this != &sample)
{
this->m_Length = sample.m_Length;
this->m_Width = sample.m_Width;
this->m_Height = sample.m_Height;
}
}
CCube& CCube::operator=(const CCube &sample)
{
cout << "Assignment operator: operator=(const CCube &sample)" << endl;
//
// 保護:禁止設值給自己
if (this != &sample)
{
this->m_Length = sample.m_Length;
this->m_Width = sample.m_Width;
this->m_Height = sample.m_Height;
}
return *this;
}
double CCube::getVolume() const
{
return (this->m_Length * this->m_Width * this->m_Height);
}
|
註釋
[編輯]參考資料
[編輯]- ^ Stroustrup, Bjarne. The C++ Programming Language 3. Addison-Wesley. 2000: 283–4. ISBN 978-0201700732.
- ^ Koenig, Andrew; Barbara E. Moo. C++ Made Easier: The Rule of Three. Dr. Dobb's Journal. 2001-06-01 [2009-09-08].
- ^ Karlsson, Bjorn; Wilson, Matthew. The Law of the Big Two. The C++ Source. Artima. 2004-10-01 [2008-01-22]. (原始內容存檔於2012-03-17).
- ^ 比雅尼·史特勞斯特魯普. The C++ Programming Language. : 第 271 頁.