从 set_new_handler 来看泛型的互斥特性

从 set_new_handler 来看泛型的互斥特性

引言

关于 set_new_handlereffctive c++ 中有写,这里就跳过,这次只是讲如何偏门的利用泛型特性。
如果有好几个类都需要重写new方法,我们需要重写很多operator new,因为我们同样需要的是这几个类都有特定的new的异常捕获函数,而不能因为继承导致所有的类共用一个异常捕获函数

栗子

下面的泛型类,我们可以发现,根本没有使用到这个T类型,那么为什么要这么做?
我们是为了继承,在面向对象中,我们总是用着继承的方式来使用重复的代码。
我们只是希望每个继承自NewHandlerSupport的类,都拥有互斥的NewHandlerSupport(更准确的说是自己的static成员 currentHanlder)
这样我们就不用每个类都要重写operator newcurrentHandler了。

#include<iostream>
using namespace std;


class OriginHandler
{
	public:
	    //其意义在于在构造函数中记录传进来的new_handler
	    //在析构函数中设置构造函数中传进来的new_handler 
	    //也就是只有它被移除的时候才会真正的设置
	    //下面会用到它,也许那时候你会懂得这个玩意的作用
		explicit OriginHandler(std::new_handler nh):handler(nh){}
		~OriginHandler(){
			std::set_new_handler(handler);
		}
	private:
		OriginHandler(const OriginHandler&); //禁止拷贝
		OriginHandler& operator=(const OriginHandler&);
		std::new_handler handler;
}


template<typename T>
class NewHandlerSupport{
	public:
		static void* operator new(size_t size);
        static void operator delete(void* pdead,size_t size);
        static void* operator new[](size_t size);
        static void operator delete[](void* pdead,size_t size);
		static std::new_handler setNewHandler(std::new_handler p);
	private:
		static std::new_handler currentHanlder; 
}
template<typename T>
std::new_handler NewHandlerSupport<T>::currentHanlder = NULL; //定义静态new_handler句柄 为空

template<typename T>
std::new_handler NewHandlerSupport<T>::setNewHandler(std::new_handler p) throw() //写一个类专属的setnewhandler方法
{
	std::new_handler oldHanlder = currentHanlder;
	currentHanlder = p;
	return oldHanlder;
};

template<typename T>
void* NewHandlerSupport<T>::operator new(size_t size)
{
	std::new_handler old = std::set_new_handler(currentHanlder);//设置new的异常触发为currentHanlder
	
	//OriginHandler构造函数并不会设置
	//只是为了如果在下面malloc触发异常,OriginHandler析构会设置回之前的handler
	OriginHandler h(old);
	
    return malloc(size);
}

template<typename T>
void NewHandlerSupport<T>::operator delete(void *pdead,size_t size)
{
    free(pdead);
}

template<typename T>
void* NewHandlerSupport<T>::operator new[](size_t size)
{
	std::new_handler old = std::set_new_handler(currentHanlder);
	
	OriginHandler h(old);
	
    return malloc(size);
}

template<typename T>
void NewHandlerSupport<T>::operator delete[](void *pdead, size_t size)
{
    free(pdead);
}

真正的意义

真正的意义就在于当我们继承它,我们在编译器编译后,就可以拥有独立的代码块,它的意义就在于让我们的父类产生互斥性
这样我们只要继承自NewHandlerSupport<T>,我们就可以拥有每个类专属的setNewHandler方法,且互相并不会影响。

class Foo: public NewHandlerSupport<Foo>
{
    public:
        Foo(){}
        ~Foo(){}
};



int main()
{
	void outOfMem();

	//我们的Foo::setNewHandler仅仅只对Foo类有效
	std::set_new_handler fooOldHanlder = Foo::setNewHandler(outOfMem);
	
    Foo* pf = new Foo();
    Foo* pf1 = new Foo[10];
    delete pf;
    delete[] pf1;
    
	Foo::setNewHandler(fooOldHanlder);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没事干写博客玩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值