operator new和new operator

在面向对象语言的程序开发中,我们习惯的用
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);
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容