这个问题看了很多次,忘了很多次,最近在重温内存池时又看了下,做个笔记吧。
首先是两个名词:new表达式,new操作符,
默认情况下当你写下如下语句时:
Foo* foo = new Foo;(这里是new-expression),实际执行了三个步骤:
1:new表达式调用一个operator new的标准库函数,分配一块足够大、原始的、未命名的内存空间
2:编译器运行相应的构造函数,并传入初始值
3:对象分配空间并构造完成,返回一个指向该对象的指针
delete foo,实际执行了两个相反的步骤:
1:调用该对象的析构函数
2:调用operator delete标准库函数,回收空间
c++中new/delete有如下级别:
- global new/delete
- class specific new/delete 
 通过代码来说明问题比较直观
- 重载全局操作符 - #include <iostream> 
 #include <stdlib.h>
class Foo
{
public:
    Foo()
    {
        std::cout << FUNCTION << std::endl;
    }
    ~Foo()
    {
        std::cout << FUNCTION << std::endl;
    }
};
//重载全局new操作符,和一般的操作符重载类似
void operator new(size_t sz)
{
    std::cout << FUNCTION << std::endl;
    void m = malloc(sz);
    if(!m)
    {
        std::cerr << “out of memory” << std::endl;
    }
return m;
}
//重载全局delete操作符,和一般的操作符重载类似
void operator delete(void* m)
{
    std::cout << FUNCTION << std::endl;
    free(m);
}
int main(int argc, const char argv[])
{
    //new-expression(表达式)
    //首先调用全局的operator(操作符) new分配内存,再调用构造函数
    Foo foo = new Foo;
    //delete-expression
    //首先调用析构函数,再调用全局的operator(操作符) delete释放内存
    delete foo;
return 0;
}
- 类操作符#include <cstddef> 
 #include <iostream>
 #include <new>
class Framis
{
    enum { sz = 10 };
    char c[sz]; // To take up space, not used
    static unsigned char pool[];
    static bool alloc_map[];
public:
    enum { psize = 100 };  // frami allowed
    Framis() { std::cout << FUNCTION << std::endl; }
    ~Framis() { std::cout << FUNCTION << std::endl; }
    void operator new(size_t) throw(std::bad_alloc);
    void operator delete(void);
};
unsigned char Framis::pool[psize * sizeof(Framis)];
bool Framis::alloc_map[psize] = {false};
// Size is ignored – assume a Framis object
void Framis::operator new(size_t) throw(std::bad_alloc)
{
    for(int i = 0; i < psize; i++)
    {
        if(!alloc_map[i])
        {
            std::cout << “using block “ << i << “ … “;
            alloc_map[i] = true; // Mark it used
            return pool + (i  sizeof(Framis));
        }
    }
    std::cout << “out of memory” << std::endl;
    throw std::bad_alloc();
}
void Framis::operator delete(void* m)
{
    if(!m) return; // Check for null pointer
    // Assume it was created in the pool
    // Calculate which block number it is:
    unsigned long block = (unsigned long)m - (unsigned long)pool;
    block /= sizeof(Framis);
    std::cout << “freeing block “ << block << std::endl;
    // Mark it free:
    alloc_map[block] = false;
}
int main()
{
    Framis f[Framis::psize];
    try
    {
        for(int i = 0; i < Framis::psize; i++)
        {
            f[i] = new Framis;
        }
        new Framis; // std::cout of memory
    }
    catch(std::bad_alloc)
    {
        std::cerr << “out of memory!” << std::endl;
    }
    delete f[10];
    f[10] = 0;
    // Use released memory:
    Framis x = new Framis;
    delete x;
    for(int j = 0; j < Framis::psize; j++)
    {
        delete f[j]; // Delete f[10] OK
    }
return 0;
}
上面的例子是从<<think in c++>>中copy过来的,类的new/delete操作符函数,尽管你可以不写static关键字,但是编译器其实把其当做static函数的。
另外还有个叫做placement new/delete表达式的重载,可以在指定的地址空间上构造/析构对象。