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 mem; //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[]时,就传递数组中所有元素的字节数。


编译器对operator new的扩展,更像如下这般:

void *operator new(std::size_t size)
{
	if (size == 0) size = 1;//对于size为0,也要保证返回唯一内存地址
	void *mem = nullptr;
	try
	{
		if (void *mem = malloc(size))
		{
			//调用默认的构造函数对分配的内存进行初始化
			mem = MyClass::MyClass(mem);
		}
	}
	catch (...)
	{
		throw;
	}
	return mem;
}




本专栏目录

所有内容的目录




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值