Почему тривиальный копируемый класс требует, чтобы деструктор был тривиальным

Основываться на стандарте 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).

Насколько я понимаю, тривиально копируемый класс это то, что может быть скопировано побитовым копированием.
Так что интуиция и причина требовать тривиальный деструктор который не связан с побитовой копией.

2

Решение

Причина достаточно проста. Тривиально копируемое означает, что допустимым и определенным поведением является копирование одного объекта A поверх другого B. Очевидно, что деструктор для B вызываться не будет, поэтому он должен быть тривиальным.

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

3

Другие решения

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

Это всего лишь предположение, хотя

0

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

C ++ позволяет все это для тривиально копируемых типов.

Если тип действительно является просто блоком битов … почему его уничтожение должно включать в себя нечто большее, чем просто освобождение памяти? Или, что более важно, если его уничтожение требует большего, чем освобождение памяти, действительно просто блок битов?

Ответ C ++ — нет, это не так. Вернее, мы не можем доказывать что это не просто блок битов.

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

0