C++拾遗--new delete 重载
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[]时,就传递数组中所有元素的字节数。
本专栏目录
所有内容的目录
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。