1)  new操作符(new operator)和operator new函数的区别:

下面的代码:
string *ps = new string("Memory Management");
使用的new是new操作符,这个操作符就像sizeof一样是内置于语言本身的。它所完成的功能分成两部分:首先分配足够的内存以便容纳所请求类型的对象(如上面的string对象);其次它会调用构造函数初始化刚刚分配的内存中的对象。new操作符总是做这两件事,我们不能以任何方式改变它的行为。

new操作符函数调用的那个用来完成必需的内存分配的函数就是operator new函数,我们可以重写或重载的就是这个函数。
函数operator new函数通常这样声明:
void *operator new(size_t size);
返回值的类型是void*,因为这个函数返回一个指针,这个指针指向原生的、未经初始化的一块内存;参数size指定要分配的内存的大小(字节为单位)。我们可以通过增加额外的参数重载operator new函数,但第一个参数的类型必须是size_t。

operator new函数的调用方式和普通函数一样:
void *rawMemory = operator new(sizeof(string));
就像malloc,operator new的唯一职责就是分配内存。把operator new函数返回的未经处理的指针转换成一个对象时new 操作符的工作,当编译器遇到下面的语句:
string *ps = new string("Memory Management");
它生成的代码与下面的相似:
void *memory = operator new(sizeof(string));
call string::string("Memory Management") on *memory;
string *ps = static_cast<string*>(memory);
上面第二步包含了构造函数的调用,程序员是不允许这样直接调用构造函数的,但编译器不受这个限制。

2) 有时我们确实想直接调用构造函数(尽管这是行不通的)。
在一个已存在的对象上调用构造函数是没有意义的,因为构造函数是用来初始化对象的,而一个对象只有在给它赋初值的时候初始化一次。
有时有些内存已经被分配但是尚未初始化,而我们需要在这块内存中构造一个对象,此时我们可以使用operator new函数的一个标准的重载版本:placement new函数。placement new允许我们在一个特定的位置“放置”对象,起到了调用一个构造函数的效果。
class ACEWidget
{
public :
ACEWidget(int widgetSize);
....
};
ACEWidget *constructWidgetInBuffer(void *buffer, int widgetSize)
{
return new (buffer) ACEWidget(widgetSize);
}
上面代码中的new操作符需要一个额外的变量buffer,当new操作符隐式调用operator new函数时,把这个变量传给它。被调用的operator new函数除了带有强制的参数size_t外,还必须接受void*指针参数,指向构造对象占用的内存空间,此时,这个operator new就是placement new:
void *operator new(size_t, void *location)
{
return location;
}
在placement new的情况下,调用者很清楚指针location是什么类型的指针,因为他知道对象应该放在哪里。placement new必须做的就是返回传递给它的指针。size_t参数在这里没有用到,因为它是强制性的参数,所以没有名字,以防止编译器发出警告说它没有被使用。(也就是说,placement new的实现忽略了表示大小的实参,直接返回其第二个参数。)
placement new是标准C++库的一部分,为了使用placement new,需要包含#include <new>

总结:如果想在堆上建立一个对象,那就使用new操作符,它既分配内存又为对象调用构造函数;如果仅仅想分配内存,那就调用operator new函数,它不会调用构造函数;如果想定制在堆对象被建立时的内存分配过程,就写一个自己的operator new函数,然后使用new操作符,new操作符会调用定制的operator new函数;如果想在一块已经有指针指向的内存里建立一个对象,就是用placement new。

注意:placement new函数不允许重写。

3) 函数operator delete和delete操作符的关系与operator new函数和new操作符的关系一样。
string *ps;
//.......
delete ps;
中的delete ps,编译器的理解差不多是:
ps->~string();
operator delete(ps);

因此,如果只想处理原始的、未被初始化的内存,可以调用operator new函数获得内存和operator delete函数释放内存:
void *buffer = operator new(10*sizeof(char));
//.........
operator delete(buffer);
而这与C中调用malloc和free等同。

如果使用placement new函数在内存中创建对象,应该避免针对这块内存使用delete操作符。因为delete操作符隐式调用operator delete函数来释放内存,但是包含对象的内存最初不是operator new函数分配的,placement只是返回传递给它的指针。此时应该显式调用对象的析构函数来销毁构造函数所建立的对象。