前言
因为c++ 可以定义 不完整类型的指针或者引用,那么当我们delete 不完整类型指针的时候会发生未定义行为,一般只会释放调相应内存不会调相应的析构函数。
场景
因为c++ 是分离编译,所以可能某个源文件进行了delete 不完整类型,这个时候编译器也不会从后面的依赖文件寻找具体的析构函数,所以这个时候就会发生未定义行为就像下面的列子,这个时候就坑了
test.cc
class A;
void Fun(A* p)
{
delete p;
}
main.cc
class A{
};
void Fun(A*p);
int main () {
A* p ;
Fun(p);
return 0;
}
g++ test.cc main.cc
check 不完整类型
下面这个表达式三段理解
- sizeof(T) 不完整类型应该报错
- 如果 1 不报错, 那么表达式变为 char [-1] ,这个时候声明一个负数数组应当报错
- 如果这个时候不报错,那么 sizeof ( char[-1]) ,求一个 char[-1] 类型的大小,这个时候会最终报错
typedef char must_complete_type[ (sizeof(T)) ? 1 : -1];
(void) sizeof(must_complete_type);