码迷,mamicode.com
首页 > 其他好文 > 详细

重载类的new和delete运算符成员函数

时间:2017-06-16 23:08:39      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:c++

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

#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <new>
using std::cout;
using std::endl;
using std::cerr;
using std::bad_alloc;
//void out_of_memory(){
//  cerr << "memory exhausted!\n";
//  exit(-1);
//}
class TestType {
  static int cnt;
  int num;
  enum { sz = 20 };
  char c[sz]; // To take up space, not used
  static unsigned char pool[];
  static bool alloc_map[];
public:
  enum { psize = 5 };
  TestType() { num = cnt++; cout << "TestType(), num = " << num << endl; }
  ~TestType() { cout << "~TestType(), num = " << num << endl; --cnt; }
  void* operator new(size_t) throw(bad_alloc);
  void operator delete(void*);
};
unsigned char TestType::pool[psize * sizeof(TestType)];
bool TestType::alloc_map[psize] = {false};
int TestType::cnt = 0;
void* TestType::operator new(size_t _size) throw(bad_alloc) {
  for(int i = 0; i < psize; i++)
    if(!alloc_map[i]) {
      cout << "using block " << i << " ... \n";
      alloc_map[i] = true; // Mark it used
      return pool + (i * sizeof(TestType));
    }
  cout << "to throw bad_alloc" << endl;
  throw bad_alloc();
}
void TestType::operator delete(void* m) {
  // Check for null pointer
  if(!m){
    cout << "null pointer\n";
    return;
  }
  // Assume it was created in the pool
  // Calculate which block number it is:
  unsigned long block = (unsigned long)m - (unsigned long)pool;
  block /= sizeof(TestType);
  cout << "freeing block " << block << endl;
  assert(block >= 0 && block <= psize);
  // Mark it free:
  alloc_map[block] = false;
}
int main() {
//  std::set_new_handler(out_of_memory);
  TestType* f[TestType::psize];
  try {
    for(int i = 0; i < TestType::psize; i++)
      f[i] = new TestType;
    new TestType; // Out of memory
  } catch(bad_alloc &) {
    cerr << "Out of memory!" << endl;
  }
  for(int j = 0; j < TestType::psize; j++){
    cout << "delete " << j << ": ";
    delete f[j]; // Delete f[cti] OK
  }
  TestType *pf;
  try {
    pf = new TestType[TestType::psize];
  } catch(bad_alloc &) {
    cerr << "Out of memory!" << endl;
  }
  delete []pf;
}

运行结果:
frank@userver:~/project/test/cpp/newdel$ ./a.out
using block 0 ...
TestType(), num = 0
using block 1 ...
TestType(), num = 1
using block 2 ...
TestType(), num = 2
using block 3 ...
TestType(), num = 3
using block 4 ...
TestType(), num = 4
to throw bad_alloc
Out of memory!
delete 0: ~TestType(), num = 0
freeing block 0
delete 1: ~TestType(), num = 1
freeing block 1
delete 2: ~TestType(), num = 2
freeing block 2
delete 3: ~TestType(), num = 3
freeing block 3
delete 4: ~TestType(), num = 4
freeing block 4
TestType(), num = 0
TestType(), num = 1
TestType(), num = 2
TestType(), num = 3
TestType(), num = 4
~TestType(), num = 4
~TestType(), num = 3
~TestType(), num = 2
~TestType(), num = 1
~TestType(), num = 0


本文出自 “用C++写诗” 博客,谢绝转载!

重载类的new和delete运算符成员函数

标签:c++

原文地址:http://frankniefaquan.blog.51cto.com/12613979/1939159

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!