最近在关注Boost库中智能指针的相关知识,剖析到下面的一段代码,在头文件checked_delete.hpp中的用于释放空间的类模板函
checked_array_delete(T * x);:
template<class T> inline void checked_array_delete(T * x)
{
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete [] x;
}
代码很简单,但表达的东西却很隐晦,其实这是一种不完全类型检测:T如果不是不完全类型那么sizeof(T)就应该是type_must_be_complete[-1],数组是不能为负数的,所以就会报错;
什么又是不完全类型呢?简单理解就是类型的定义不完整,比如只对类进行了声明,却未定义;
//AAA.h
#include <iostream>
2 class AAA
3 {
4 public:
5 AAA()
6 {
7 std::cout<<"AAA"<<std::endl;
8 }
9 ~AAA()
10 {
11 std::cout<<"~AAA"<<std::endl;
12 }
13 };
//Bmain.cpp
1 #include <iostream>
1 #include <iostream>
2 class AAA;
3 class B
4 {
5 public:
6 void deleteAAA(AAA* pb)
7 {
8 delete pb;
9 }
10
11 };
12
13
14 int main()
15 {
16 B b;
17 //b.deleteAAA(new AAA); **//假设这句代码被注释,没有用到daletaAAA,此时编译器只会出现一个警告**
18 return 0;
19 }
//但如果void deleteAAA(AAA* pb)这个函数是这样定义时,就会及时检测错误
void deleteBB(BB* pb)
{
typedef char type_must_be_complete[sizeof(BB) ? 0:-1]; //如果不是不完全类型那么sizeof(T)就应该是type_must_be_complete[-1],数组是不能为负数的,所以就会报错;
(void) sizeof(type_must_be_complete);
delete pb;
}
我们应该尽量让错误在编译时出现,而不是在执行时,所用可以用到不完全类型检测的方法,在编译的时候就会对这种情况报错;