Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1585158
  • 博文数量: 399
  • 博客积分: 8508
  • 博客等级: 中将
  • 技术积分: 5302
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-14 09:28
个人简介

能力强的人善于解决问题,有智慧的人善于绕过问题。 区别很微妙,小心谨慎做后者。

文章分类

全部博文(399)

文章存档

2018年(3)

2017年(1)

2016年(1)

2015年(69)

2013年(14)

2012年(17)

2011年(12)

2010年(189)

2009年(93)

分类: LINUX

2010-08-09 09:39:00

以下大部分来自于 More Effective C++:理解new和delete, 添加了一些在 STL vector中实际操作的理解)

new操作符(new operator)就象sizeof一样是语言内置的,你不能改变它的含义(注意,这里是说new操作符,而不是new函数),它的功能总是一样的。它要完成的功能分成两部分。第一部分是分配足够的内存以便容纳所需类型的对象。第二部分是它调用构造函数初始化内存中的对象。new操作符总是做这两件事情,你不能以任何方式改变它的行为。

你所能改变的是如何为对象分配内存。new操作符调用一个函数来完成必需的内存分配,你能够重写或重载这个函数来改变它的行为。new操作符为分配内存所调用函数的名字是operator new
函数operator new 通常这样声明:
void * operator new(size_t size);
返回值类型是void*,因为这个函数返回一个未经处理(raw)的指针,未初始化的内存。(假如你喜欢,你能写一种operator new函数,在返回一个指针之前能够初始化内存以存储一些数值,但是一般不这么做。)参数size_t确定分配多少内存。你能增加额外的参数重载函数 operator new,但是第一个参数类型必须是size_t。

你一般不会直接调用operator new,但是一旦这么做,你可以象调用其它函数一样调用它:
void *rawMemory = operator new(sizeof(string));
操作符operator new将返回一个指针,指向一块足够容纳一个string类型对象的内存
就象malloc一样,operator new的职责只是分配内存。它对构造函数一无所知。operator new所了解的是内存分配。把operator new 返回的未经处理的指针传递给一个对象是new操作符的工作。

在STL的vector里面的分配器就是直接使用了 operator new 函数来分配内存

int *ptr=new int [5];

这个语句实现了,在堆中查找一块足够存储一个拥有5个整形数的数组的内存,且数组的首地址赋予了指针ptr。

Placement new
有时你确实想直接调用构造函数。在一个已存在的对象上调用构造函数是没有意义的,因为构造函数用来初始化对象,而一个对象仅仅能在给它初值时被初始化一次。但是有时你有一些已经被分配但是尚未处理的的(raw)内存,你需要在这些内存中构造一个对象。你可以使用一个非凡的operator new ,它被称为placement new。

template
inline void passive_vector::_Construct(T* p)
{
    //new(static_cast(p)) T();
    new(p) T();
}

template
inline void passive_vector::_Construct(T* p, T& val)
{
    //new(static_cast(p)) T(val);
    new(p) T(val);
}

注意,必须include , 上面的代码才能编译通过(实际上时必须include

上面的函数,在已经分配好的内存p上执行一个构造函数T()

这是new操作符的一个用法,需要使用一个额外的变量(p),当new操作符隐含调用operator new函数时,把这个变量传递给它。被调用的operator new函数除了待有强制的参数size_t外,还必须接受void*指针参数,指向构造对象占用的内存空间。这个operator new就是placement new,它看上去象这样:
void * operator new(size_t, void *location)
{
return location;
}

这可能比你期望的要简单,但是这就是placement new需要做的事情。在使用placement new的情况下,调用者已经获得了指向内存的指针,因为调用者知道对象应该放在哪里。placement new必须做的就是返回转递给它的指针。

placement new是标准C++库的一部分,   为了使用placement new,你必须使用语句#include

总结:

1)你想在堆上建立一个对象,应该用new操作符。它既分配内存又为对象调用构造函数。

2)你仅仅想分配内存,就应该调用operator new函数;它不会调用构造函数。

3)你想定制自己的在堆对象被建立时的内存分配过程,你应该写你自己的operator new函数,然后使用new操作符,new操作符会调用你定制的operator new。

4)你想在一块已经获得指针的内存里建立一个对象,应该用placement new。

类似地,也有delete操作符和delete函数

阅读(2374) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~