今天看《STL源码剖析》,突然看到一个叫__type_traits<T>的名词。
当容器进行范围destoy的时候,其函数接受first和last的迭代器,若[first,last)范围内所有的元素都调用析构函数,但这个类型T的析构又是无关痛痒的,则会损耗效率。 __type_trais<T>可以判别该类型T的的析构函数是否无关痛痒,若是(__true_type),则什么都不做,否则调用其析构函数。
STL的destroy函数原型:
步骤解释:
1.首先容器触发destroy(Iterator first, Iterator last)
2.value_type(first)取得容器当前存储的类型T*,然后调用__destroy(Iterator first, Iterator last, T*)
3.在__destroy函数里, 利用typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor, 判断类型T的析构是否存在特性,并调用__destroy_aux,传入trivial_destructor
(若类型T是无特性的,其会定义typedef __true_type has_trivial_destructor, 否则定义typedef __false_type has_trivial_destructor)
4.若存在特性,则会调用到__destroy_aux(Iterator, Iterator, __false_type), 并逐一对[first, last)范围内的元素进行析构
5.若不存在特性,则会调用到__destroy_aux(Iterator, Iterator, __true_type), 并什么都不做
ps:更具体的理解可以看看http://blog.csdn.net/sanlongcai/article/details/1786647 该博文浅显地讲出了type trait的概念,而其测试代码也很容易懂。
此处顺便记录下本人对上述博文的测试代码的修改测试,供日后回味。 :)
1 #ifndef TEST_CLASS_H 2 #define TEST_CLASS_H 3 4 #include <iostream> 5 using std::cout; 6 using std::endl; 7 8 class TestClass 9 { 10 public: 11 TestClass() 12 { 13 cout << "TestClass constructor call" << endl; 14 data = new int(3); 15 } 16 TestClass(const TestClass& test_class) 17 { 18 cout << "TestClass copy constructor call. copy data:" 19 << *(test_class.data) << endl; 20 data = new int; 21 *data = *(test_class.data) * 2; 22 } 23 ~TestClass() 24 { 25 cout << "TestClass destructor call. delete the data:" << *data << endl; 26 delete data; 27 } 28 private: 29 int *data; 30 }; 31 32 #endif
TestClass.h
1 // my_type_traits.h开始 2 #ifndef MY_TYPE_TRAITS_H 3 #define MY_TYPE_TRAITS_H 4 5 //#include "test_class.h" 6 7 struct my_true_type { 8 }; 9 10 struct my_false_type { 11 }; 12 13 template <class T> 14 struct my_type_traits 15 { 16 typedef my_false_type has_trivial_destructor; 17 }; 18 19 template<> struct my_type_traits<int> 20 { 21 typedef my_true_type has_trivial_destructor; 22 }; 23 24 //template<> struct my_type_traits<TestClass> 25 //{ 26 // typedef my_true_type has_trivial_destructor; 27 //}; //若删除对TestClass的注释,则TestClass将会被定义成没有特性的析构的类 28 29 #endif 30 // my_type_traits.h结束
my_type_traits.h
1 // my_destruct.h开始 2 #ifndef MY_DESTRUCT_H 3 #define MY_DESTRUCT_H 4 #include <iostream> 5 6 #include "my_type_traits.h" 7 8 using std::cout; 9 using std::endl; 10 11 template <class T1, class T2> 12 inline void myconstruct(T1 *p, const T2& value) 13 { 14 new (p) T1(value); 15 } 16 17 template <class T> 18 inline void mydestroy(T *p) 19 { 20 typedef typename my_type_traits<T>::has_trivial_destructor trivial_destructor; //此处获得类型T是否没有特性析构 21 _mydestroy(p, trivial_destructor()); 22 } 23 24 template <class T> 25 inline void _mydestroy(T *p, my_true_type) 26 { 27 cout << " do the trivial destructor " << endl; 28 } 29 30 template <class T> 31 inline void _mydestroy(T *p, my_false_type) 32 { 33 cout << " do the real destructor " << endl; 34 p->~T(); 35 } 36 37 #endif 38 // my_destruct.h结束
my_destruct.h
1 #include "test_class.h" 2 #include "my_destruct.h" 3 4 int main(void) 5 { 6 { 7 TestClass *test_class_buf; 8 TestClass test_class; 9 10 test_class_buf = (TestClass *)malloc(sizeof(TestClass)); 11 myconstruct(test_class_buf, test_class); 12 mydestroy(test_class_buf); 13 free(test_class_buf); 14 } 15 16 { 17 int *int_p; 18 int_p = new int; 19 mydestroy(int_p); 20 free(int_p); 21 } 22 }
main.cpp
该图是当my_type_traits.h中对TestClass的has_trivial_destructor定义为__true_type的语句注释后的结果
下图则是未注释的结果