写点什么

C++ 构造那些事:三五 O 法则

作者:行者孙
  • 2021 年 12 月 14 日
  • 本文字数:1159 字

    阅读完需:约 4 分钟

我们知道如果不提供默认/copy/copy-assignment 构造函数,编译器在需要的时候会为我们自动生成相应的构造函数,那么在 C++编程实践中,什么时候需要提供构造函数,什么时候要利用编译器的自动生成功能呢?大佬们总结为三五法则还有零法则。

在 C++ 中一个类有以下 6 种特殊的成员函数需要关注:


// https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#note-99class X {public:    // ...    X(); // default constructor    virtual ~X();            // destructor (virtual if X is meant to be a base class)    X(const X&);             // copy constructor    X& operator=(const X&);  // copy assignment    X(X&&);                  // move constructor    X& operator=(X&&);       // move assignment};
复制代码


  • 以上六种特殊的成员函数可以声明为类似 X() = default 让编译器自动生成, 或者声明为 X() = delete 阻止编译器自动生成相应的函数定义

  • X::X() 默认构造函数 如果没有声明为 =delete,编译器将会自动生成定义。但是如果用户声明了其他形式的构造函数如X(int x) , 编译器将不会自动生成,除非用户手动定义。

  • X(const X&)X& operator=(const X&) 如果没有用户指定,在需要的时候编译器会自动生成,内容为对成员的值拷贝,如果是指针成员将是“浅复制”。

  • 对除 default ctor 之外的特殊成员函数的声明,哪怕是=defaultdelete,将会阻止编译器生成 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

  1. https://en.cppreference.com/w/cpp/language/rule_of_three

  2. Cpp Core Guide # C21

发布于: 1 小时前阅读数: 7
用户头像

行者孙

关注

Nothing replaces hard work 2018.09.17 加入

充满好奇心,终身学习者。 博客:https://01io.tech

评论

发布
暂无评论
C++构造那些事:三五O法则