Основываться на стандарте C ++. тривиальный копируемый класс определяются следующим образом:
Согласно 9/5,
A trivially copyable class is a class that:
- has no non-trivial copy constructors (12.8),
- has no non-trivial move constructors (12.8),
- has no non-trivial copy assignment operators (13.5.3, 12.8),
- has no non-trivial move assignment operators (13.5.3, 12.8), and
- has a trivial destructor (12.4).
Насколько я понимаю, тривиально копируемый класс это то, что может быть скопировано побитовым копированием.
Так что интуиция и причина требовать тривиальный деструктор который не связан с побитовой копией.
Причина достаточно проста. Тривиально копируемое означает, что допустимым и определенным поведением является копирование одного объекта A поверх другого B. Очевидно, что деструктор для B вызываться не будет, поэтому он должен быть тривиальным.
Есть описание времени жизни объекта в N3797 3.8 / 4, которое, кажется, покрывает ситуацию. Тем не менее, может существовать лазейка в отношении повторного использования хранилища и отказа от вызова нетривиального деструктора, если программа не зависит от побочных эффектов деструктора.
Нетривиальный деструктор, вероятно, подразумевает, что вы удаляете некоторые указатели.
Если дело обстоит именно так, кажется, что ошибка делает побитовое копирование класса, так как тогда у вас будет два экземпляра, которые оба попытаются удалить один и тот же указатель.
Это всего лишь предположение, хотя
В объектной модели C ++ тип, который удовлетворяет концепции Trivially Copyable, логически представляет собой тот, чьи данные являются просто блоком битов. Тип — это просто набор фундаментальных объектов данных с некоторыми значениями. Таким образом, копирование блока битов в какое-то хранилище является совершенно допустимой операцией, и теперь это хранилище должно (если соответствующим образом выровнено) содержать такой объект. Кроме того, вполне разумно скопировать блок битов во временное хранилище (независимо от выравнивания), а затем скопировать его обратно в объект соответствующего типа.
C ++ позволяет все это для тривиально копируемых типов.
Если тип действительно является просто блоком битов … почему его уничтожение должно включать в себя нечто большее, чем просто освобождение памяти? Или, что более важно, если его уничтожение требует большего, чем освобождение памяти, действительно просто блок битов?
Ответ C ++ — нет, это не так. Вернее, мы не можем доказывать что это не просто блок битов.
В том-то и дело в правилах Trivial Copyability: все дело в доказательствах. В соответствии с тривиальными правилами копирования мы можем доказывать что такой тип просто блок битов. Другие типы может быть быть блоками битов, в зависимости от того, что делают эти функции. Но поскольку мы не можем доказать, являются ли они или нет, поэтому мы запрещаем обращаться с ними как таковыми.