前言
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,則調用局部的,否則調用全局的。
細節
------------------------------分割線------------------------------
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個章節中: