# V832. It's better to use '= default;' syntax instead of empty body.

Если в классе специальные функции объявляются с '= default', класс остается тривиально копируемым. Это потенциально поможет копировать и инициализировать такой класс более оптимально.

Правила формирования специальных функций сложные. Поэтому при написании классов/структур лучшим решением будет определить явно некоторые из них для лучшего понимания кода. Вот примеры таких специальных функций: конструктор по умолчанию, конструктор копирования, оператор копирования, деструктор, конструктор перемещения, оператор перемещения.

    struct MyClass
    {
      int x;
      int y;
      MyClass() {}
      ~MyClass() {}
    };

или так:

    // header
    struct MyClass
    {
      int x;
      int y;
    };

    // cpp-file
    MyClass::MyClass() {}
    MyClass::~MyClass() {}

Такие функции (конструктор по умолчанию и деструктор в примере) программист определяет с пустым телом. Однако при таком подходе класс может стать нетривиально копируемым, из-за чего компилятор не всегда сможет сгенерировать более оптимальный код. Поэтому C++11 вводит синтаксис '= default' для специальных функций:

    struct MyClass
    {
      int x;
      int y;
      MyClass() = default;
      ~MyClass() = default;
    };

Помимо того, что компилятор сам сгенерирует тела специальных функций, он сможет вывести спецификаторы 'constexpr' и 'noexcept' для них автоматически.

Стоит отметить, что при переносе определения специальных функций из тела класса компилятор считает их определенными пользователем. Это может привести к пессимизации, поэтому '= default' лучше по возможности добавлять непосредственно в теле класса.

Срабатывание не выдается, если:

- используемый стандарт ниже C++11;
- у конструктора есть список инициализации;
- класс не содержит нестатических полей.

## Примечание про идиому PIMPL

Определения больших классов внутри заголовочного файла могут многократно увеличивать время компиляции проекта. Чтобы его сократить, можно вынести реализацию класса в отдельный компилируемый файл, а в заголовочном файле оставить только объявления методов и указатель на реализацию класса. Такой подход носит название PIMPL. Вот пример такого класса:

    #include <memory>

    // header
    class MyClass
    {
      class impl;
      std::unique_ptr<impl> pimpl;
    public:
      void DoSomething();
      ~MyClass();
    };

    // cpp-file
    class MyClass::impl
    {
    public:
      impl()
      {
        // does nothing
      }

      ~impl()
      {
        // does nothing
      }

      void DoSomething()
      {
        // ....
      }
    };

    void MyClass::DoSomething()
    {
      pimpl->DoSomething();
    }

    MyClass::~MyClass() {}

Добавление '= default' к деструктору в теле класса приведет к ошибкам компиляции, т.к. деструктор класса 'MyClass::impl' на данном этапе неизвестен (деструктор нужен для 'std::unique_ptr'). Поэтому при таком подходе реализация специальных функций переносится в компилируемый файл.

При переносе определения специальных функций из тела класса их пустые тела также можно заменить на '= default'. Это не даст прироста производительности, однако сделает код чище и проще для восприятия:

    MyClass::~MyClass() = default;