C++ 构造那些事:三五 O 法则
我们知道如果不提供默认/copy/copy-assignment 构造函数,编译器在需要的时候会为我们自动生成相应的构造函数,那么在 C++编程实践中,什么时候需要提供构造函数,什么时候要利用编译器的自动生成功能呢?大佬们总结为三五法则还有零法则。
在 C++ 中一个类有以下 6 种特殊的成员函数需要关注:
以上六种特殊的成员函数可以声明为类似
X() = default
让编译器自动生成, 或者声明为X() = delete
阻止编译器自动生成相应的函数定义X::X()
默认构造函数 如果没有声明为=delete
,编译器将会自动生成定义。但是如果用户声明了其他形式的构造函数如X(int x)
, 编译器将不会自动生成,除非用户手动定义。X(const X&)
和X& operator=(const X&)
如果没有用户指定,在需要的时候编译器会自动生成,内容为对成员的值拷贝,如果是指针成员将是“浅复制”。对除 default ctor 之外的特殊成员函数的声明,哪怕是
=default
或delete
,将会阻止编译器生成 move constructor/assignment; 将会导致该类无法使用移动语义;如果程序员只声明了
move constructor/assignment
, 编译器隐式生成的复制和赋值语义将会声明为delete
, 也就是 class 将是 move-only 的。
Rule Of Three
如果需要自定义(user-defined)析构函数,自定义的 copy 构造函数和自定义的 copy-assignment 操作符, 这三个往往同时需要自定义。
具体而言:需要对资源进行管理(例如 raw pointer, POSIX 文件描述符)的时候,需要自己实现析构/复制/赋值构造函数, 编译器自动生成的往往是浅复制。
Rule of Five
Because the presence of a user-defined destructor, copy-constructor, or copy-assignment operator prevents implicit definition of the move constructor and the move assignment operator, any class for which move semantics are desirable, has to declare all five special member functions:
自定义(user-defined)析构函数,自定义的 copy 构造函数或自定义的 copy-assignment 操作符的情况下,编译器不会生成默认的 move 构造函数和 move-assignment 操作符。在这种情况下,如果需要移动语义,需要自己定义这 5 个特殊成员函数。
Rule of Zero
如果不需要手动定义, 就不要定义,一切让它默认。
Reference
https://en.cppreference.com/w/cpp/language/rule_of_three
版权声明: 本文为 InfoQ 作者【行者孙】的原创文章。
原文链接:【http://xie.infoq.cn/article/badc6e549645bee92cda02553】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论