Удаление объекта с частным деструктором

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

Другая полезная вещь, которую можно вставить к docstrings, doctest.

9
задан Sam 11 August 2014 в 09:11
поделиться

3 ответа

Вы пытаются удалить объект неполного типа класса. Стандарт C ++ говорит, что в этом случае вы получите неопределенное поведение (5.3.5 / 5):

Если удаляемый объект имеет неполный тип класса на момент удаления, а полный класс имеет нетривиальный деструктор или функция освобождения, поведение не определено.

Чтобы обнаружить такие случаи, вы можете использовать boost :: checked_delete :

template<typename T> 
inline void checked_delete( T* p )
{
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete p;
}
15
ответ дан 4 December 2019 в 08:15
поделиться

Поскольку тип SomeClass не объявляется полностью при вызове оператора delete .

Удаление такого указателя является неопределенным поведением, но на практике большинство компиляторов просто освободит память (если указатель был не NULL) и не вызовет деструктор.

Например, g ++ выдаст предупреждение об этой проблеме:

foo.cpp: In function 'int main(int, char**)':
foo.cpp:6: warning: possible problem detected in invocation of delete operator:
foo.cpp:5: warning: 'boo' has incomplete type
foo.cpp:1: warning: forward declaration of 'struct SomeClass'
foo.cpp:6: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
4
ответ дан 4 December 2019 в 08:15
поделиться

Этот код вызывает неопределенное поведение (UB). UB в C ++ - удалить объект неполного типа, имеющий нетривиальный деструктор. И в вашем коде тип SomeClass является неполным в точке delete , и у него есть нетривиальный деструктор. Компиляторы обычно выдают предупреждение об этом, поскольку в C ++ формально это не нарушение ограничения.

Итак, строго говоря, ваш код не «работает». Он просто компилирует и при запуске делает что-то undefined .

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

7
ответ дан 4 December 2019 в 08:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: