条款8:写operator new和operator delete时要遵循常规

1. 首先我被一个问题所困恼:条款7中的operator new是这么写的,但条款8中的new却多了一个while。回头再仔细看下条款7,原来条款7中的operator new只处理了第一次分配内存失败的异常。

//条款7中的operator new
template<class T>  
void* NewHandlerSupport<T>::operator new(size_t size)  
{  
    void* memory = NULL;  
    new_handler old_handler = ::set_new_handler(current_handler);  
  
    try  
    {  
        memory = ::operator new(size);  
    }  
    catch (std::bad_alloc&)  
    {  
        set_new_handler(old_handler);  
        throw;  
    }  
  
    set_new_handler(old_handler);  
    return memory;  
}  

 2. operator new要遵循哪些常规:a)要有正确的返回值. b)内存不够异常处理. c)处理请求0字节内存分配. d)避免隐藏标准new. e) 非类成员的operator new 和类成员的operator new区别. 其看起来会像下面这样:

//条款8中非类成员的operator new
void* operator new(size_t size)
{
	if(0 == size)
	{
		size = 1;
	}
	while(1)
	{
		new_handler handler = NULL;
		void* memory = NULL;

		handler = set_new_handler(NULL);
		set_new_handler(handler);
		memory = ::operator new(size);

		if(NULL != memory)
			return memory;

		if(handler) 
			(*handler)();
		else 
			throw std::bad_alloc();
	}
}

//条款8中类成员的operator new
class X
{
public:
    static void* operator new(size_t size);
    //...
private:
    //...
};

void* X::operator new(size_t size)
{
    if(size != sizeof(X)) //如果X的子类的size大于sizeof(X)
        return ::operator new(size);

    /*if(0 == size)
    {
        size = 1;
    }*/
    while(1)
    {
        new_handler handler = NULL;
        void* memory = NULL;

        handler = set_new_handler(NULL);
        set_new_handler(handler);
        memory = ::operator new(size);

        if(NULL != memory)
            return memory;

        if(handler) 
            (*handler)();
        else 
            throw std::bad_alloc();
    }
} 

 

3. operator delete要遵循哪些常规:a)C++保证删除空指针永远是安全的,意味着我们只需要保证我们的指针不是野指针就无大碍. b)同样的非类成员的operator delete和类成员的operator delete有区别.

//非类成员的operator delete
void operator delete(void* memory)
{
    if(NULL == memory)
        return;
    
    ::operator delete(memory);
    return;
}

//类成员的operator delete
class X
{
public:
	static void* operator new(size_t size);
	static void operator delete(void* memory, size_t size);
	//...
private:
	//...
};

void X::operator delete(void* memory, size_t size)
{
	if(NULL == memory)
		return;

	if(size != sizeof(X))				//如果X的子类的size大于sizeof(X)
	{
		::operator delete(memory);		//标准的delete
		return;
	}
	
	//自定义的delete,这里也调用标准的delete
	::operator delete(memory);
}





   
posted @ 2012-06-11 17:34  $逝水无痕$  阅读(165)  评论(0编辑  收藏  举报