Подтвердить что ты не робот

Какая разница между деструктором "= default" и пустым деструктором?

Я хочу, чтобы пользователь моего класса не использовал его как автоматическую переменную, поэтому я пишу код следующим образом:

class A {
private:
  ~A() = default;
};

int main() {
  A a;
}

Я ожидаю, что код не будет скомпилирован, но g++ компилирует его без ошибок.

Однако, когда я меняю код на:

class A {
private:
  ~A(){}
};

int main() {
  A a;
}

Теперь g++ дает ошибку, что ~A() является приватным, как и мое ожидание.

Какая разница между деструктором "= default" и пустым деструктором?

4b9b3361

Ответ 1

Ваш первый пример не должен компилироваться. Это представляет собой ошибку в компиляторе, которую он компилирует. Эта ошибка исправлена ​​в gcc 4.9 и более поздних версиях.

Деструктор, определенный с помощью = default, в этом случае тривиален. Это можно обнаружить с помощью std::is_trivially_destructible<A>::value.

Обновление

С++ 11 (и С++ 14) утверждают, что если у одного есть объявленный пользователем деструктор (и если у вас нет какого-либо объявленного пользователем элемента перемещения move), то неявное генерирование конструктора копирования и оператор присваивания копиям все еще существует, но это поведение устарело. Если вы полагаетесь на это, ваш компилятор может дать вам предупреждение об отказе (или, возможно, нет).

И

~A() = default;

и

~A() {};

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

Если вы объявляете элементы перемещения (с объявлением деструктора или без него), члены копии неявно удаляются.