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 ,基本算是完成了。

你可能感兴趣的:(STL(二):construct 与 destroy)