c++重载operator new和operator delete

 

1:C++标准说:An allocation function shall be a class member function or a global function; a program is ill-formed if an allocation function is declared in a namespace scope other than global scope or declared static in global scope.


必须是全局函数或类成员函数,而不能是全局之外的名字空间或static全局函数。

2:new operator的行为
对于如下代码:
    foo* p = new(参数1,参数2,…… ) foo(……);
    ……其他代码……
    delete p;
编译器将生成如下代码:
    调用 p = operator new( size_t 需要的大小,参数1,参数2,…… ); // 这里有可能抛出std::bad_alloc,但无须在new operator中捕捉
    如果构造foo不会抛出异常 // 即foo的构造函数后面显式的声明了 throw()
        在p指向处构造foo(参数1,参数2,……);
        return p;
    否则
        try
        {
            在p指向处构造foo(参数1,参数2,……);
            return p;
        }
        catch(...)
        {
            调用 operator delete( void* p, 参数1,参数2,…… );
            throw;
        }
    ……其他代码……
    调用 operator delete( void* p );

从上面的描述可以看出两点:
    a. 除了第一个参数外,其它参数和 operator new 都相同的 operator delete 称为相匹配的 operator delete
    b. 相匹配的 operator delete 仅在 operator new 成功,对象构造失败时被调用。而其他地方则一直调用 operator delete( void* p )。
       (如果不这么设计的话,编译器得为每一个p绑定当初调用它的operator new相匹配的operator delete的地址,以及当初调用时的实参,汗!!! )

3:全局形式的operator new伪代码
void* operator new( size_t size ) // 包括其他形式
{
    if( 0 == size ) // 须要注意
        size = 1;

    while(1)
    {
        分配size字节内存;
        if(分配成功)
            return 指向内存的指针;

        new_handler globalhandler = set_new_handler(0);
        set_new_handler(globalhandler);

        if( globalhandler )
            (*globalhandler)();
        else
            throw std::bad_alloc();
    }
}
void operator delete( void* raw )
{
    if( 0 == raw ) // 须要注意
        return;
    ...
}
须要说明的是,编译器本身就隐含着一个 void* operator new( size_t ),所以重载全局operator new必须加其他参数以示区别。
一般重载分配函数时都会重载三个,分别是 void* operator new( size_t, …… ),void operator delete( void*, …… ),以及一般形式的 void operator delete( void* )。

4. set_new_handler的作用
    set_new_handler设置一个函数,此函数将在分配内存失败时被调用,见3中的代码。
    从3中的代码还能看得出,new_handler必须有主动退出的功能,否则就会导致operator new内部死循环。因此newhandler的一般形式是:
    void mynewhandler()
    {
        if( 有可能使得operator new成功(比如释放部分内存) )
        {
            做有可能使得operator new成功的事
            return;
        }
        // 主动退出
        或 abort/exit 直接退出程序
        或 set_new_handler(其他newhandler);
        或 set_new_handler(0)
        或 throw bad_alloc()或派生类 // 这一种比较好,不粗鲁的关闭程序,也不更改其他设置
    }
须要说明的是,没有类形式的set_new_handler,但这也无所谓,你可以自己写。(见《Effective C++ 2e》条款7)

5. 类形式的operator new伪代码:
struct base
{
    ...
    static void* operator new( size_t size );
    static void operator delete( void* raw );
};
void* base::operator new( size_t size )
{
    if( sizeof(base) != size ) // 须要注意
        return ::operator new(size);

    类似于3 // 注意“没有类形式的set_new_handler”
}
void base::operator delete( void* raw )
{
    if( sizeof(base) != size ) // 须要注意
    {
        ::operator delete(raw);
        return;
    }
    同3
}

 

 

原文出处:  http://blog.vckbase.com/bruceteen/archive/2009/05/27/37427.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值