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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重载类的new和delete运算符成员函数相关的知识,希望对你有一定的参考价值。

重载类的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;
}

运行结果:
[email protected]:~/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运算符成员函数的主要内容,如果未能解决你的问题,请参考以下文章

类模板 友元重载形式 各种运算符重载 new delete ++ = +=

如果类具有析构函数/ delete [],则成员运算符new []的参数“size”会增加

C++运算符重载中 重载为类的成员函数和重载为类的友元函数 的区别是啥?

c语言,c++,哪些运算符不能重载?

C++:= default & = delete

C++类和对象—— 类的6个默认成员函数及日期类的实现