STL(二):construct 与 destroy

STL 中关于对象的构造和销毁是使用construct 和 destroy 函数 的。
这个内容写在文件stl_construct.h 中。

_type_traits

在讲主题之前,有必要介绍一个_type_traits 与若干概念。
简单而言,这个类的作用就是萃取出我们需要的各种内容。

它的模板代码如下:

//POD  的意思是:Plain Old Data ,即标量型或传统的C struct 型别
template<typename T>
struct _type_traits
{
    typedef _false_type has_trivial_default_constructor;
    typedef _false_type has_trivial_copy_constructor;
    typedef _false_type has_trivial_assignment_operator;
    typedef _false_type has_trivial_destructor;
    typedef _false_type is_POD_type;
};

它想要表达的意思是,你给我的模板参数,它是否有平凡的构造函数(trivial_constructor)、平凡的复制构造函数、平凡的赋值函数、平凡的析构函数与及是否是POD 变量。

POD 变量的解析:

Plain Old Data ,即标量型或传统的C struct 型别

POD 变量显然满足上面列的条件。
那需要区分是和否,我们就需要两个类:

struct _true_type {};
struct _false_type {};

这两个类的作用就是用于区分,从而进行函数重载。对的,traits 技术就是基于函数重载完成的。

下面会有一堆的特化版本,这里只列出一种:

template<> struct _type_traits<bool>
{
    typedef _true_type has_trivial_default_constructor;
    typedef _true_type has_trivial_copy_constructor;
    typedef _true_type has_trivial_assignment_operator;
    typedef _true_type has_trivial_destructor;
    typedef _true_type is_POD_type;
};

除了bool ,还有其他的内置变量。
对于我们自定义的类,都是默认为false_type 的。如果你希望修改,那就要自己去特化它。

construct

construct 的函数比较简单,只要用placement new 就可以了:

template<typename T1, typename T2>
inline void construct(T1* p, const T2& value)
{
    new (p) T1(value);
}


template<typename T1>
inline void construct(T1* p)
{
    new (p) T1;
}

destroy

destroy 函数的行为就有一点点复杂了,它会依据萃取出的类型信息,选择不同的执行函数。如果是trivial_destructor, 那么什么都不做。否则一一析构。
第一个版本,只需要析构一个变量:

template<typename T1>
inline void destroy(T1* p)
{
    p->~T1();
}

那就乖乖析构好了。注意,析构函数是可以在类外显示调用的,构造函数就不可以。我第一次看到的时候,非常震惊。

第二个版本是接受一个区间范围,然后执行合适的行为。

template<typename Forward_iterator, typename T>
inline void _destroy_aux(Forward_iterator first, Forward_iterator last, T*)
{
    typedef typename _type_traits<T>::has_trivial_destructor trivial_destructor;
    _destroy_aux(first, last, trivial_destructor() );
}

//第二个版本,如果析构函数是trivial destructor 那就什么都不做
template<typename Forward_iterator>
inline void _destroy_aux(Forward_iterator first, Forward_iterator last, _true_type)  {}

//第三个版本,要一一调用
template<typename Forward_iterator>
inline void _destroy_aux(Forward_iterator first, Forward_iterator last, _false_type)
{
    for(; first!=last; ++first)
    {
        destroy(&*first);
    }
}

template<typename Forward_iterator>
inline void destroy(Forward_iterator first, Forward_iterator last)
{
    //利用trait 技术,进而求取最合适的析构函数
    //value_type 就是把first 中的实际类型给提取出来
    _destroy_aux(first, last, _value_type(first) );
}

温馨提示,从下往上看。
_value_type 函数的定义如下:

//为什么不直接返回pointer呢?
//我想是因为不想被const 干扰吧
template<typename Iter>
inline typename iterator_traits<Iter>::value_type* _value_type(const Iter& )
{
    return static_cast< typename iterator_traits<Iter>::value_type* > (0);
}

返回这个类型的指针,这是为了获得这个类型的信息。
那这里又遇到了iterator_traits,看这个:traits
(果真好烦)

最后进行一些特化:


inline void destroy(char*, char* ) {}
inline void destroy(int*, int* ) {}
inline void destroy(long*, long* ) {}
inline void destroy(float*, float* ) {}
inline void destroy(double*, double* ) {}
inline void destroy(wchar_t*, wchar_t* ) {}

nice ,基本算是完成了。

#3 0x000000000046ef07 in ~_Vector_base (this=0x6a4ead0, __in_chrg=<value optimized out>) at /usr/include/c++/4.4/bits/stl_vector.h:132 #4 0x000000000046dd2d in ~vector (this=0x6a4ead0, __in_chrg=<value optimized out>) at /usr/include/c++/4.4/bits/stl_vector.h:313 #5 0x000000000046b7c8 in ~ZXJC_LineCover (this=0x6a4ea30, __in_chrg=<value optimized out>) at ../../web/demonitordll/dbproc.h:236 #6 0x000000000046b7e2 in std::_Destroy<ZXJC_LineCover> (__pointer=0x6a4ea30) at /usr/include/c++/4.4/bits/stl_construct.h:83 #7 0x000000000046795a in std::_Destroy_aux<false>::__destroy<ZXJC_LineCover*> (__first=0x6a4ea30, __last=0x6a4ea18) at /usr/include/c++/4.4/bits/stl_construct.h:93 #8 0x000000000045bc7f in std::_Destroy<ZXJC_LineCover*> (__first=0x6a4e960, __last=0x6a4ea18) at /usr/include/c++/4.4/bits/stl_construct.h:116 #9 0x000000000044920f in std::_Destroy<ZXJC_LineCover*, ZXJC_LineCover> (__first=0x6a4e960, __last=0x6a4ea18) at /usr/include/c++/4.4/bits/stl_construct.h:142 #10 0x00007f3769464bde in std::vector<ZXJC_LineCover, std::allocator<ZXJC_LineCover> >::_M_insert_aux (this=0x7f374ee9aca0, __position=..., __x=...) at /usr/include/c++/4.4/bits/vector.tcc:359 #11 0x00007f376945c985 in std::vector<ZXJC_LineCover, std::allocator<ZXJC_LineCover> >::push_back (this=0x7f374ee9aca0, __x=...) at /usr/include/c++/4.4/bits/stl_vector.h:741 #12 0x00007f3769445ca0 in CDBProc::GetLineCoverageRate (this=0x7f3758003690, o_fStatistRate=@0x7f374ee9acdc, o_strErr=..., feederVec=...) at dbproc.cpp:3472
最新发布
06-13
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值