跳转到内容

三法则

本页使用了标题或全文手工转换
维基百科,自由的百科全书

三法则(英语:Rule of Three)以及五法则C++里,它是一个以设计的基本原则而制定的定律。

规则

它的要求是,假如有明显定义英语Declaration (computer programming)下列其中一个成员函式,那么程序员必须写入其他两个成员函式到类别内,也就是说下列三个成员函式缺一不可[注 1] [1]

上述三个函式是特别的成员函式英语Special member functions,假如程式设计师没有自行定义或宣告这三个函式,编译器会自动地建立他们并且编译到应用程式内。然而,如果程式设计师仅定义其中一个,其馀两个函式仍然会由编译器自动产生,这种混杂的情况非常容易产生程式设计师难以预期的错误。三法则的存在,正是提醒程式设计师避免那样的陷阱。 三法则这个专有名词是由马歇尔·克来恩于1991年创立[注 2][2]

它的修正版本是,假如类别有用到RAII,可以不必定义解构子,也就是所谓的二大定律[注 3][3]。 因为隐性产生的建构子与设定运算子可以很容易地复制类别内所有的资料成员[4],当资料成员是指标型态时,指标位址会随著类别而跟著被复制[注 4]。要注意的是,直接地复制指标位址是一项非常危险的动作,所以只要类别有封装指标型态的资料结构,或是类别有封装外部参照的资料成员,例如指标型态的资料成员,程式设计师应该为此而定义显性的复制建构子与设定运算子[注 5]

五法则

C++11新增两个法则,称为五法则[注 6]

  • 解构子
  • 复制建构子
  • 设定运算子
  • 移动建构子[注 7]
  • 移动复制运算符[注 8]

范例

C/C++ 原始码《计算方块体积》三法则范例
头文件 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);
}

注释

  1. ^ 三法则,英语:Rule of Three;三大定律,英语:the Law of The Big Three;大三律,英语:The Big Three
  2. ^ 马歇尔·克来恩,英语:Marshall Cline
  3. ^ 二大定律,英语:The Law of The Big Two
  4. ^ 隐性产生,英语:implicitly-generated,由编译器自动产生
  5. ^ 显性,英语:explicit,由程式设计师来编写清楚明确的定义
  6. ^ 五法则,英语:Rule of Five
  7. ^ 移动建构子,英语:move constructor
  8. ^ 移动指定运算子,英语:move assignment operator

参考资料

  1. ^ Stroustrup, Bjarne. The C++ Programming Language 3. Addison-Wesley. 2000: 283–4. ISBN 978-0201700732. 
  2. ^ Koenig, Andrew; Barbara E. Moo. C++ Made Easier: The Rule of Three. Dr. Dobb's Journal. 2001-06-01 [2009-09-08]. 
  3. ^ Karlsson, Bjorn; Wilson, Matthew. The Law of the Big Two. The C++ Source. Artima. 2004-10-01 [2008-01-22]. (原始内容存档于2012-03-17). 
  4. ^ 比雅尼·史特劳斯特鲁普. The C++ Programming Language. : 第 271 页. 

相关条目