operator new 函数
operator new
作为一个 global namespace 下的普通函数,有三个重载:
c++
1 | void* operator new (std::size_t size); |
可以直接被这样调用:
c++
1 | MyClass * p = (MyClass*) ::operator new (sizeof(MyClass)); |
- 第一种叫 throwing allocation,如果分配失败会抛一个
bad_alloc
的异常,分配成功就返回新分配空间的起始地址。 - 第二种叫 nothrow allocation,如果分配失败不会抛异常而是返回一个 null,分配成功就返回新分配空间的起始地址。
- 第三种叫 placement,需要 include
<new>
,不会试图分配空间,而是仅仅返回 ptr(看上去没啥用,但是用在 new-expression 中还是很有用的)
new 表达式
上面是直接调用 operator new
这个函数时它的行为,如果用在 new-expression 中会有所不同:首先会以普通函数的形式调用 operator new
,这一步如上所述,如果成功会调用 new-expression 中类的构造函数,构造到刚才 operator new
返回的地址中,最后返回一个相应类型的指针。
第一种是最简单的 new-expression:
c++1
2
3MyClass * p1 = new MyClass;
// allocates memory by calling: operator new (sizeof(MyClass))
// and then constructs an object at the newly allocated space第二种需要在 new 后面加上
(std::nothrow)
:c++1
2
3MyClass * p2 = new (std::nothrow) MyClass;
// allocates memory by calling: operator new (sizeof(MyClass), std::nothrow)
// and then constructs an object at the newly allocated space第三种需要在 new 后面加上一个地址:
c++1
2
3new (p2) MyClass;
// does not allocate memory -- calls: operator new (sizeof(MyClass), p2)
// but constructs an object at p2
总结
总结一下就是仅仅调用 ::operator new
是分配空间(第三种除外),而 new-expression 则是分配空间加构造对象,前两种是在分配的新空间上构造,第三种是在指定的地址构造。