前言

在看一些开源代码,会发现delete可能会先判断是否为不完全类型

1
2
3
4
...
typedef char MustCompleteType[sizeof(T) == 0 ? -1 : 1];
delete obj;
...

这是有必要的,因为delete不安全类型并不算error而是waring。
这篇博客就是讨论这个。

标准是怎么说的

If the object being deleted has incomplete class type at the point of deletion and the complete class has a
non-trivial destructor or a deallocation function, the behavior is undefined.
— N3337 3.4.5 Delete
因此delete不完全类型可能会导致crash,也可能仅仅是单纯的不调用析构函数罢了。但无论如何,这都是应该避免的。

避免手法

显然,我们需要的是编译时断言,因为一个类型是否为完全类型是编译时确定的。
上面展示的是一种做法,另外一种做法是利用C++11的静态断言(static_assert):

1
static_assert(sizeof(T) > 0, "T must be complete type");

API

boost中也有类似的设施:checked_delete()

1
2
3
4
5
6
7
8
9
10
11
12
13
template<typename T>
inline void checked_delete(T *obj)
{
static_assert(sizeof(T) > 0, "The type of the object must be complete type");
delete obj;
}

template<typename T>
inline void checked_array_delete(T *arr)
{
static_assert(sizeof(T) > 0, "The element type of the array must be complete type");
delete []arr;
}