background image

深入 C++的 new

new 是 C++的一个关键字,同时也是操作符关于 new 的话题非常多,因为它确实比较复
杂,也非常神秘,下面我将把我了解到的与 new 有关的内容做一个总结

new 的过程

当我们使用关键字 new 在堆上动态创建一个对象时,它实际上做了三件事:获得一

块内存空间调用构造函数返回正确的指针当然,如果我们创建的是简单类型的变量,那
么第二步会被省略假如我们定义了如下一个类 A:
class A
{
   int i;
public:
   A(int _i) :i(_i*_i) {}
   void Say()  { printf("i=%dn", i); }
};
//调用 new:
A* pa = new A(3);

那么上述动态创建一个对象的过程大致相当于以下三句话(只是大致上):
虽然从效果上看,这三句话也得到了一个有效的指向堆上的 A 对象的指针 pa,但区

别在于,当 malloc 失败时,它不会调用分配内存失败处理程序 new_handler,而使用
new 的话会的因此我们还是要尽可能的使用 new,除非有一些特殊的需求
new 的三种形态

到目前为止,本文所提到的 new 都是指的 new operator 或称为 new expression,但

事实上在 C++中一提到 new,至少可能代表以下三种含义:new operatoroperator 
newplacement new

new operator 就是我们平时所使用的 new,其行为就是前面所说的三个步骤,我们

不能更改它但具体到某一步骤中的行为,如果它不满足我们的具体要求时,我们是有可
能更改它的三个步骤中最后一步只是简单的做一个指针的类型转换,没什么可说的,并
且在编译出的代码中也并不需要这种转换,只是人为的认识罢了但前两步就有些内容了

new operator 的第一步分配内存实际上是通过调用 operator new 来完成的,这里的

new 实际上是像加减乘除一样的操作符,因此也是可以重载的 operator new 默认情况下
首先调用分配内存的代码,尝试得到一段堆上的空间,如果成功就返回,如果失败,则
转而去调用一个 new_hander,然后继续重复前面过程如果我们对这个过程不满意,就可
以重载 operator new,来设置我们希望的行为例如:
class A
{
public:
   void* operator new(size_t size)
   {
       printf("operator new calledn");
       return ::operator new(size);