不完全类型检测 “typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];”

最近在关注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; 
  }  

我们应该尽量让错误在编译时出现,而不是在执行时,所用可以用到不完全类型检测的方法,在编译的时候就会对这种情况报错;

猜你喜欢

转载自blog.csdn.net/return_cc/article/details/79393103