空间配置器 之 空间的析构与构造

目录

一.简述

二.对象的构造与析构:

2.1 空间的构造:

2.2  空间的析构:

三.写在后面


一.简述

        声明:本文主要是对侯捷老师的STL源码剖析这本书的整理与自我思考。

        以STL的角度来说,空间配置器不是最重要要介绍的东西,但是一切容器中元素的创建与删除,都与空间配置器有着紧密的联系。

        SCI中包含有两种空间配置器:std::allocator与std::alloc。allocator只是对(::operator new与::operator delete)的一种简单包装而已,在这里我主要讲述std::alloc。

        总所周知,C++内存配置操作和释放操作是这样的:

    class Foo{...}
    Foo* pf = new Foo;//配置内存,然后释放对象
    delete pf; //将对象析构,然后释放内存

        其中的new主要包含两个部分:(1)调用::operator new 配置内存;(2)调用Foo::Foo()构造对象。delete也包含两个部分:(1)调用Foo::~Foo();(2)::operator delete释放内存。

        在STL中,配置器定义于<memory>之中,SGI<memory>下面有两个文件:

    #include <stl_alloc.h>     //负责内存空间的配置与释放
    #include <stl_construct.h> //负责对象内容的构造与析构

二.对象的构造与析构:

2.1 空间的构造:

    template<class TI,class T2>
    inline void construct(T1* p,const T2& value){
      new (p) T1(value); //调用TI::T1(value)
    }

        以上函数中,传入需要构造对象的地址p以及对象的值value,然后利用new以及T1的构造函数,创建了一个值为T1的对象并且将其存入地址p中。

2.2  空间的析构:

        

template <class _ForwardIterator>
inline void destroy(_ForwardIterator __first, _ForwardIterator __last) {
	_Destroy(__first, __last);                        //调用_Destroy()
}

//如果元素的数值型别有无用的析构函数,函数体无操作,是上述函数的特化版本
template <class _ForwardIterator>
inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {}
 
template <class _ForwardIterator>
inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) {
	__destroy(__first, __last, __VALUE_TYPE(__first));    //调用__destroy()
}
 
template <class _ForwardIterator, class _Tp>
inline void
__destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*)
{
	typedef typename __type_traits<_Tp>::has_trivial_destructor
		_Trivial_destructor;
	__destroy_aux(__first, __last, _Trivial_destructor());  //调用__destroy_aux()
}
 
template <class _ForwardIterator>
void
__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type)
{
	for (; __first != __last; ++__first)
		destroy(&*__first);    //调用destroy()
}

        对于destory进行使用的时候,一般要传入容器对应的两个迭代器(一个指向需要析构元素的首地址,一个指向需要析构元素的后一个地址)。

        1.STL对destory()函数进行了重载,泛华版本传入的是两个迭代器模板(template<class ForwardIterator>),特化版本是传入两个char*或者wchar*类型的指针。

        2.所以当destory() 传入两个char*或者wchar*类型的指针时,析构函数什么都不做。

        3.当传入其他类型,如迭代器或者其他类型的指针时,就会调用_destory()函数,此函数会进行一个(特别的)操作:利用迭代器中的type_traits判断传入的迭代器所指向的元素类型的has_trivial_desturctor(即:是否该迭代器所指向的元素类型的析构函数是无关痛痒的)。如果是无关痛痒的,就什么都不做,如果该元素的类型拥有比较完备的析构函数,则调用此类型的析构函数,将两个迭代器(指针)之间的值进行逐一析构。

        4.此处,有读者可能会问,哪些元素类型是无关痛痒的?

        此问题涉及到了迭代器中的部分知识,在此我进行简略回答:如果是char,signedchar,unsignedchar,short,unsigned short,int,unsigned int,long,unsigned long,float,double,long double以及T*这些的析构函数都是无关痛痒的;如果是shape以及用户自己定义的class类型等,那么STL都是默认拥有自己类型的析构函数的。

三.写在后面

        以上关于内存析构的部分,可能写的过于冗长,不过结合实际代码进行解读可能会更好地去理解。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值