Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / C++拾遗--new delete 重载

前言new和delete是操作动态内存的一对操作。对它们重载可以对内存管理进行有效的定制。正文1.局部重载特别针对某一类型,对new和delete进行重载,可以对该类型对象的动态创建实行监控。如下代码:代码一#include <iostream>
using namespace std;
class MyClass
{
public:
 MyClass()
 {
  cout << "MyClass()" << endl;
 }
 ~MyClass()
 {
  cout << "~MyClass()" << endl;
 }
 void *operator new(std::size_t size)
 {
  cout << "局部new call" << endl;
  void *mem = malloc(size);   
  if (mem)   //内存分配失败,则返回0
   return malloc(size);
  else
   throw bad_alloc();   //内存分配失败,抛出异常
 }
 void operator delete(void *ptr)
 {
  cout << "局部delete call" << endl;
  //不为空,则调用free释放内存
  if (ptr)
  {
   free(ptr);
  } 
 }
};
int main()
{
 cout << "******局部new delete重载演示***by David***" << endl;
 MyClass *my = new MyClass;
 delete my;
 cin.get();
 return 0;
}运行运行结果表明表达式new整合了内存分配和构造函数。先调用malloc分配内存,然后调用指定类型并相匹配的构造函数初始化该段内存。表达式delete整合了析构函数和内存释放。先调用类的析构函数释放资源,后调用free释放分配的内存。代码二下面一个例子提供了对内存分配进行监控的一种方法。#include <iostream>
using namespace std;
class MyClass
{
public:
 //count记录未释放的对象个数
 static int count;
 int a;
 MyClass()
 {
  cout << "MyClass()" << endl;
  count++;
 }
 ~MyClass()
 {
  cout << "~MyClass()" << endl;
  count--;
 }
 //new 局部重载
 void *operator new(size_t size)
 {
  cout << "局部new call" << endl;
  void *mem = malloc(size);    //内存分配失败,则返回0
  if (mem)
   return malloc(size);
  else
   throw bad_alloc();   //内存分配失败,抛出异常
 }
 //new[] 局部重载
 void *operator new[](std::size_t size)
 {
  cout << "局部new[] call" << endl;
  void *mem = malloc(size);    //内存分配失败,则返回0
  if (mem)
   return malloc(size);
  else
   throw bad_alloc();   //内存分配失败,抛出异常
 }
 //delete 局部重载
 void operator delete(void *ptr)
 {
  cout << "局部delete call" << endl;
  //不为空,则调用free释放内存
  if (ptr)
  {
   free(ptr);
  }
 }
 //delete[] 局部重载
 void operator delete[](void *ptr)
 {
  cout << "局部delete[] call" << endl;
  //ptr不为空,则调用free释放内存
  if (ptr)
  {
   free(ptr);
  }
 }
};
int MyClass::count = 0;
int main()
{
 cout << "******new delete 局部重载演示***by David***" << endl;
 cout << "起始MyClass::count = " << MyClass::count << endl;
 MyClass *my = new MyClass;
 delete my;
 cout << "-----------------" << endl;
 MyClass my1;
 cout << "-----------------" << endl;
 MyClass *mys = new MyClass[5];
 cout << "MyClass::count = " << MyClass::count << endl;
 delete[]mys;
 cout << "MyClass::count = " << MyClass::count << endl;
 cin.get();
 return 0;
}运行2.全局重载对全局的new和delete重载可以监控所有类型的内存分配。#include <iostream>
#include <string>
using namespace std;
class MyClass
{
public:
 MyClass()
 {
  cout << "MyClass()" << endl;
 }
 ~MyClass()
 {
  cout << "~MyClass()" << endl;
 }
 void *operator new(std::size_t size)
 {
  cout << "MyClass::new重载" << endl;
  void *mem = malloc(size);
  if (mem)
   return mem;
  else
   throw bad_alloc();
 }
 void *operator new[](std::size_t size)
 {
  cout << "MyClass::new[]重载" << endl;
  void *mem = malloc(size);
  if (mem)
   return mem;
  else
   throw bad_alloc();
 }
 void operator delete(void *ptr)
 {
  cout << "MyClass::delete重载" << endl;
  if (ptr)
  {
   free(ptr);
  }
 }
 void operator delete[](void *ptr)
 {
  cout << "MyClass::delete[]重载" << endl;
  if (ptr)
  {
   free(ptr);
  }
 }
};
//全局new重载
void *operator new(std::size_t size)
{
 cout << "全局new重载" << endl;
 void *mem = malloc(size);
 if (mem)
  return mem;
 else
  throw bad_alloc();
}
//全局new[]重载
void *operator new[](std::size_t size)
{
 cout << "全局new[]重载" << endl;
 void *mem = malloc(size);
 if (mem)
  return mem;
 else
  throw bad_alloc();
}
//全局delete重载
void operator delete(void *ptr)
{
 cout << "全局delete重载" << endl;
 if (ptr)
 {
  free(ptr);
 }
}
//全局delete[]重载
void operator delete[](void *ptr)
{
 cout << "全局delete[]重载" << endl;
 if (ptr)
 {
  free(ptr);
 }
}
int main()
{
 cout << "******全局/局部new和delete都进行重载***by David***" << endl;
 int *p = new int;
 delete p;
 cout << "-------------------" << endl;
 double *ds = new double[10];
 delete[]ds;
 cout << "-------------------" << endl;
 MyClass *my = new MyClass;
 delete my;
 cout << "-------------------" << endl;
 MyClass *mys = new MyClass[3];
 delete[]mys;
 cin.get();
 return 0;
}运行如果类型重新定义了new 和 delete,则调用局部的,否则调用全局的。细节
  • operator new或operator new[]的返回类型必须是void*。
  • operator delete或operator delete[]的返回类型必须是void。
  • 类中重载的new和delete都是隐式static的。若显式声明,也不会出错。
  • size_t就是unsigned int。当编译器调用operator new时,把存储指定类型对象所需的字节数传递给size_t的形参。当调用operator new[]时,就传递数组中所有元素的字节数。
 ------------------------------分割线------------------------------C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码 http://www.linuxidc.com/Linux/2014-05/101227.htm读C++ Primer 之构造函数陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm读C++ Primer 之智能指针 http://www.linuxidc.com/Linux/2011-08/40177.htm读C++ Primer 之句柄类 http://www.linuxidc.com/Linux/2011-08/40175.htm将C语言梳理一下,分布在以下10个章节中:
  1. Linux-C成长之路(一):Linux下C编程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成长之路(二):基本数据类型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成长之路(三):基本IO函数操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成长之路(四):运算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成长之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成长之路(六):函数要义 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成长之路(七):数组与指针 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成长之路(八):存储类,动态内存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成长之路(九):复合数据类型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成长之路(十):其他高级议题
本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-02/114058.htm