引言
关于 set_new_handler
,effctive c++
中有写,这里就跳过,这次只是讲如何偏门的利用泛型特性。
如果有好几个类都需要重写new方法
,我们需要重写很多
的operator new
,因为我们同样需要的是这几个类都有特定的new的异常捕获函数
,而不能因为继承
,导致所有的类共用一个异常捕获函数
。
栗子
下面的泛型类,我们可以发现,根本没有使用到这个
T
类型,那么为什么要这么做?
我们是为了继承
,在面向对象中,我们总是用着继承的方式来使用重复的代码。
我们只是希望每个继承自NewHandlerSupport
的类,都拥有互斥的NewHandlerSupport
(更准确的说是自己的static
成员currentHanlder
)
这样我们就不用每个类都要重写operator new
和currentHandler
了。
#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);
}