重载类的 new,delete,new[],delete[] 运算符成员函数
1. 调用 new 时,先分配内存,后调用构造函数。调用构造函数的行为由编译器控制。
2. 调用 delete 时,先调用析构函数,后释放内存。调用析构函数的行为由编译器控制。
重载这四个运算符函数的目的是为了控制内存的分配与释放。如果需要对某个类型频繁地创建和销毁大量的对象, 这四个运算过程可能会耗费太多的时间,并且会产生内存碎片。
这四个运算符函数的原型:
  void* operator new(size_t) throw(bad_alloc);
  void operator delete(void* pmem);
  void* operator new[](size_t sz) throw(bad_alloc);
  void operator delete[](void* pmem);
重载时必须与原型一致!
请看示例代码:

#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <new>
using std::cout;
using std::endl;
using std::cerr;
using std::bad_alloc;
using std::hex;
//void out_of_memory(){
//  cerr << "memory exhausted!\n";
//  exit(-1);
//}
template<typename T>
inline void DelObject(T *&pobj){
  delete pobj;
  pobj = 0; // Don't forget to assigne pobj as 0.
}
template<typename T>
inline void DelObjArray(T *&parr) {
  delete []parr;
  parr = 0; // Don't forget to assigne parr as 0.
}
class NewDelType {
  union {
    unsigned char ch[4];
    int val;
  }ts;
public:
  enum { psize = 10 };
  static unsigned char pool[];
  static bool alloc_map[];
public:
  NewDelType() { 
    ts.val = 0x12345678; 
     printf("%s,  this=%p, ts=(%#x,%#x,%#x,%#x,%#x)\n", __func__,this,ts.val,ts.ch[0],ts.ch[1],ts.ch[2],ts.ch[3]);
  }
  ~NewDelType() { 
     printf("%s, this=%p, ts=(%#x,%#x,%#x,%#x,%#x)\n", __func__,this,ts.val,ts.ch[0],ts.ch[1],ts.ch[2],ts.ch[3]);
  }
  void* operator new(size_t) throw(bad_alloc);
  void operator delete(void* pmem);
  void* operator new[](size_t sz) throw(bad_alloc);
  void operator delete[](void* pmem);
};
unsigned char NewDelType::pool[psize * sizeof(NewDelType)];
bool NewDelType::alloc_map[psize] = {false};
void* NewDelType::operator new(size_t) throw(bad_alloc) {
  for(int i = 0; i < psize; i++){
    if(!alloc_map[i]) {
       printf("%s, to use block %d\n", __func__, i);
      alloc_map[i] = true; // Mark it used
      return pool + (i * sizeof(NewDelType));
    }
  }
  printf("%s, to throw bad_alloc\n", __func__);
  throw bad_alloc();
}
void NewDelType::operator delete(void* pmem) {
  // Check for null pointer
  if(!pmem){
    printf("%s, null pointer\n", __func__);
    return;
  }
  // Assume it was created in the pool
  // Calculate which block number it is:
  unsigned long block = (unsigned long)pmem - (unsigned long)pool;
  block /= sizeof(NewDelType);
  printf("%s, freeing block:(%p, %lu)\n", __func__, pmem, block);
  assert(block >= 0 && block < psize && alloc_map[block] == true);
  // Mark it free:
  alloc_map[block] = false;
}
void* NewDelType::operator new[](size_t sz) throw(bad_alloc) {
  assert( (sz - 8) % sizeof(NewDelType) == 0);
  int request = (sz - 8) / sizeof(NewDelType);
  assert(request >= 0 && request <= psize);
  printf("%s, sz = %lu, reqest = %d\n", __func__, sz, request);
  int avail = 0;
  int start = -1, end = -1;
  for(int i = 0; i < psize; ++i){
    if(alloc_map[i] == false)
      ++avail;
    else
      avail = 0;
    if(avail == request){
      end = i;
      start = end + 1 - request;
      break;
    }
  }
  if(avail == request){
    for(int j = start; j <= end; ++j){
      alloc_map[j] = true; 
    }
    unsigned char *pbyte =  pool + start * sizeof(NewDelType);
    printf("%s, to use block:(%p, %d, %d)\n", __func__, pbyte, start, end);
    printf("\t");
    for(int k = 0; k < 12; ++k){
      printf("0x%x ", pbyte[k]);
    }
    printf("\n");
    return pbyte;
  }
  else{
    printf("%s, to throw bad_alloc, avail = %d\n", __func__, avail);
    throw bad_alloc();
  }
}
void NewDelType::operator delete[](void* pmem) {
  // Check for null pointer
  if(!pmem){
    printf("%s, null pointer\n", __func__);
    return;
  }
  //The quantity of objects allocated was saved in the first byte.
  //WARNING: Maybe the quantity is not saved here for every case. 
  unsigned char to_free = *(unsigned char *)pmem;
  printf("%s, pmem:(%p, %d)\n", __func__, pmem, to_free);
  printf("\t");
  unsigned char *pbyte = (unsigned char *)pmem;
  for(int k = 0; k < 12; ++k){
    printf("0x%x ", pbyte[k]);
  }
  printf("\n");
  unsigned long block = (unsigned long)pmem - (unsigned long)pool;
  block /= sizeof(NewDelType);
  int start = block;
  int end = block + to_free - 1;
  assert(start >= 0 && end < psize);
  printf("%s, freeing block: (%d, %d)\n", __func__, start, end);
  // Mark it free:
  for(int i = start; i <= end; ++i){
    assert(alloc_map[i] == true);
    alloc_map[i] = false;
  }
}
int main() {
  NewDelType *pobj1 = 0, *pobj2 = 0, *pobj3 = 0, *pobj4 = 0;
  printf("%s, NewDelType::pool:(%p ~ %p)\n", __func__, NewDelType::pool, NewDelType::pool + sizeof(NewDelType::pool) - 1);
  //set_new_handler(out_of_memory);
  try {
    pobj1 = new NewDelType;
//    DelObject<NewDelType>(pobj1);
    cout << endl;
    pobj2 = new NewDelType[9];
    DelObjArray<NewDelType>(pobj2);
    cout << endl;
//    pobj3 = new NewDelType[5];
//    cout << endl;
//
//    pobj4 = new NewDelType[6];
  } catch(bad_alloc &) {
    cerr << __func__ << ", Out of memory!" << endl;
  }
}

测试结果:

main, NewDelType::pool:(0x6023a0 ~ 0x6023c7)
operator new, to use block 0
NewDelType,  this=0x6023a0, ts=(0x12345678,0x78,0x56,0x34,0x12)

operator new [], sz = 44, reqest = 9
operator new [], to use block:(0x6023a4, 1, 9)
        0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
NewDelType,  this=0x6023ac, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023b0, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023b4, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023b8, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023bc, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023c0, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023c4, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023c8, ts=(0x12345678,0x78,0x56,0x34,0x12)
NewDelType,  this=0x6023cc, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023cc, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023c8, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023c4, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023c0, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023bc, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023b8, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023b4, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023b0, ts=(0x12345678,0x78,0x56,0x34,0x12)
~NewDelType, this=0x6023ac, ts=(0x12345678,0x78,0x56,0x34,0x12)
operator delete [], pmem:(0x6023a4, 9)
        0x9 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x78 0x56 0x34 0x12
operator delete [], freeing block: (1, 9)