在面向对象语言的程序开发中,我们习惯的用
class Info{...};
Info* info = new Info;
delete info;
这里的第二行是一个new operator的操作,包含了分配内存和构造对象这两个步骤,具体的是(1)调用::operator new分配内存(2)调用Info的构造函数构造对象。第三行是一个delete operator操作,包含了析构对象和释放内存这两个步骤,具体的是(1)调用Info的析构函数将对象析构(2)调用::operator delete释放内存。
在C++中为了精密的分工,将这两个步骤分开。内存的分配由allocator::allocate()负责,内存的释放有allocator::deallocate()负责;对象的构造由::construct()负责,对象的析构由::destroy()负责。
在STL源码解析中,STL的配置器位于<memory>文件中,内存的分配与对象的构造分别放在了stl_alloc.h与stl_construct.h这两个头文件中。stl_construct.h定义了两个基本的函数,construct()与destroy().
memory文件中主要包含了3个头文件,stl_construct.h,stl_alloc.h与stl_uninitialized.h.其他两个文件用途前面提过,这里说下stl_uninitialized.h,该文件中定义了一些全局函数,用来fill and copy大块内存的数据,具体的有全局函数un_initialized_copy(),un_initialized_fill(),un_initialized_fill_n(),这些函数对于效率都有很全面的考虑,最佳的情况会调用C标准函数memmove()直接进行内存数据的移动,最坏的情况会调用construct().
在深入construct()函数时,在实现的时候调用了placement new的操作,关于placement new操作可以参考http://www.cnblogs.com/luxiaoxun/archive/2012/08/10/2631812.html,这里做了讲解,这里简单地说下placement new的含义,是在预先分配好的缓冲区(内存)中构造一个对象。
template <class T1, class T2>
inline void construct(T1* p, const T2& value)
{
new (p) T1(value); // placement new; 调用 T1::T1(value);
}
construct()函数接收一个指针和一个初始值value,用途就是将初始值value设定到指针p所指的空间上。这个可以有placement new来完成。
destroy()函数存在两个版本,第一个版本原型如下
template <class T>
inline void destroy(T* pointer) {
pointer->~T();
}
接收一个指针,准备将该指针所指之物析构,直接调用该对象的析构函数。
第二个版本原型如下
template <class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last) {
__destroy(first, last, value_type(first));
}
接收first和last这两个迭代器Iterator,准备将[first,last)范围内的对象析构掉。
这是会产生一个问题:我们不知道具体要析构对象的范围多大,万一很大,而且每一个对象的析构函数都是trivial destructor,每一个调用这些析构函数对效率是一种伤害。这里先用value_type()取出迭代器对象所指对象的类型,然后利用__type_traits<T>判断该类型的析构函数是否是trivial destructor,若是(__true_type),则实现为空,什么都不做。否则(__false_type),循环访问[first,last),将该范围的每一个对象析构,析构每一个对象时会调用第一个版本的析构函数。关于value_type()和__type_traits<>在以后的文章中会提到。具体实现代码如下
template <class ForwardIterator, class T>
inline void __destroy(ForwardIterator first, ForwardIterator last, T)
{
typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;
__destroy_aux(first, last, trivial_destructor());
}
以下为__true_type的情况
template <class ForwardIterator>
inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {}
以下为__false_type的情况
inline void
__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) {
for ( ; first < last; ++first)
destroy(&first);
}
operator new和new operator
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 题目内容: class Fruit{int no;double weight;char key;public:vo...