本文主要记录我对big three的粗浅理解,并且参考了[C++定式模型 - 解决Big Three问题的方法],对这一问题有了更深入的理解。
问题
什么是Big Three?
三法则(英语:rule of three,the Law of The Big Three,The Big Three;三法则,三大定律)在 C++ 程序设计里,它是一个以设计的基本原则而制定的定律,三法则的要求在于,假如类有明显地定义下列其中一个成员函数,那么程序员必须连其他二个成员函数也一同编写至类内,亦即下列三个成员函数缺一不可:
- 析构函数(Destructor)
- 复制构造函数(copy constructor)
- 复制赋值运算符(copy assignment operator)
上述三个函数是特别的成员函数,假如程序员没有自行定义或是编写声明它们,那么编译器会自动地创建它们,并且会编译至应用程序内。相反地,假如程序员有定义上述三者其中一个函数,那么由编译器自动产生出来的上述三个函数是不会搭配到这个类内。三法则(Rule of three)这个专有名词是由 Marshall Cline 于 1991 年创立的。
简言之,如果显示定义 析构函数(Destructor)复制构造函数(copy constructor)复制赋值运算符(copy assignment operator)这三者其中的任意一个,需要同时显示的定义另外两个函数。
why?
那么为什么要这么做呢。先说一下,这块只是我自己的理解。先说一下big three使用的时机。当数据成员有管理动态开辟内存的指针时,需要使用该原则。其实,使用big three的时机从一部分解释了他的原因。具体来说如下:
- 以上三个函数均牵扯到对动态内存的管理
- 系统默认生成拷贝构造函数以及赋值运算函数只会完成浅拷贝(shallow copy),并且析构函数并不会释放动态开辟的内存空间。
所以,当类需要动态管理内存时,以上三个函数均涉及到动态管理内存并且系统默认生成的都不能实现该功能。所以,需要用户显示定义该部分功能。
代码
#include <iostream>
#include <cstring>
class StudentClass{
public:
StudentClass(){
std::memset( this, 0, sizeof(StudentClass) );
}
StudentClass(int num) : num_(num) {
this->grade_ = new int[num_];
}
// 拷贝构造函数
StudentClass( const StudentClass& rhs ){
this->num_ = rhs.num_;
this->grade_ = new