Нужно ли здесь соблюдать правило пяти?

Итак, на https://en.cppreference.com/w/cpp/language/rule_of_three написано:

Поскольку наличие определяемого пользователем (или = объявленного по умолчанию или = объявленного удаления) деструктора, конструктора копирования или оператора присваивания копирования предотвращает неявное определение конструктора перемещения и оператора присваивания перемещения, любой класс, для которого желательна семантика перемещения, должен объявить все пять специальных функций-членов

Итак, для этого класса я сделал следующее

      #include <string>
#include <iostream>

class Data {
private:
    std::string m_name;

public:
    Data() { m_name = "stackman"; }
    ~Data() = default;
    Data(const Data&) = delete;
    Data& operator=(const Data&) = delete;
    Data(Data&&) = delete;
    Data& operator=(Data&&) = delete;

    std::string get_name() { return m_name; }
};

int main()
{
    Data person;

    std::cout << person.get_name() << std::endl;

}

Я видел противоречивые ресурсы в Интернете, в которых говорилось, что если деструктор установлен по умолчанию и если вам не нужны другие конструкторы, вам не нужно их удалять или определять. Итак, каков наилучший план действий здесь?

1 ответ

Если вы намерены использовать деструктор по умолчанию и не собираетесь явно делать класс неперемещаемым или некопируемым, вам вообще не следует объявлять деструктор. В этом нет никакой пользы. Следуйте правилу нуля и вообще не объявляйте никаких специальных функций-членов.

В некоторых случаях вам необходимо явно указать деструктор по умолчанию, особенно если вы хотите объявить его какvirtual, но в остальном оставьте его вести себя как неявный деструктор. Проблема в том, что это отключает неявное объявление операций перемещения. Таким образом, вы должны, опять же предполагая, что вы не хотите намеренно отключать операции перемещения или копирования, явно указать значение по умолчанию для всех специальных функций-членов. Они по-прежнему будут определяться как удаленные, если реализация по умолчанию не будет работать. Это также соответствует правилу пяти, которое вы процитировали.

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

Если вы намерены явно сделать класс некопируемым или неперемещаемым, удалите соответствующие специальные функции-члены и установите остальные по умолчанию.

Другие вопросы по тегам