三五法则
- 如果一个类定义了解构函数,那么您必须同时定义或删除拷贝构造函数和拷贝赋值函数,否则出错。
- 如果一个类定义了拷贝构造函数,那么您必须同时定义或删除拷贝赋值函数,否则出错,删除可导致低效。
- 如果一个类定义了移动构造函数,那么您必须同时定义或删除移动赋值函数,否则出错,删除可导致低效。
- 如果一个类定义了拷贝构造函数或拷贝赋值函数,那么您必须最好同时定义移动构造函数或移动赋值函数,否则低效。
针对C++89,在定义一个类时,可以显示(手动定义)/隐式(编译器默认)定义该类对象在拷贝、赋值、解构时如何做。
一个类通过定义三种特殊成员成员函数来控制这些操作:拷贝构造函数、拷贝赋值函数、析构函数。
所以三法则:
- 如果一个类定义了解构函数,那么您必须同时定义或删除拷贝构造函数和拷贝赋值函数,否则出错。
- 如果一个类定义了拷贝构造函数,那么您必须同时定义或删除拷贝赋值函数,否则出错,删除可导致低效。
因为C++默认提供的拷贝赋值函数和拷贝构造函数是对成员进行浅拷贝,非常容易出现内存管理问题。
1.禁用拷贝函数:
1 | // Myvector.h |
运行结果:
1 | main.cpp:12:14: error: call to deleted constructor of 'Myvector' |
2.定义拷贝构造函数,拷贝赋值函数:
1 | // main.cpp |
运行结果:
1 | 拷贝构造 |
在较新的 C++11 标准中,为了支持移动语义,又增加了移动构造函数和移动赋值运算符,这样共有五个特殊的成员函数,所以又称为“C++五法则”。
- 如果一个类定义了移动构造函数,那么您必须同时定义或删除移动赋值函数,否则出错,删除可导致低效。
- 如果一个类定义了拷贝构造函数或拷贝赋值函数,那么您必须最好同时定义移动构造函数或移动赋值函数,否则低效。
定义移动构造函数和移动赋值函数:
1 | // main.cpp |
运行结果:
1 | 拷贝赋值 |