• 怪异的ACE_NEW_RETURN - [ACE]

    2008-04-02

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://egeho123.blogbus.com/logs/18119244.html

    ACE中使用了很多ACE_NEW_RETURN,查看了下它的声明:
    //声明于<ace/os_memory.h>
    # if defined (ACE_HAS_NEW_NOTHROW)
    #    define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
       do { POINTER = new (ACE_nothrow) CONSTRUCTOR; \
         if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \
       } while (0)
    #    define ACE_NEW(POINTER,CONSTRUCTOR) \
       do { POINTER = new(ACE_nothrow) CONSTRUCTOR; \
         if (POINTER == 0) { errno = ENOMEM; return; } \
       } while (0)
    #    define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \
       do { POINTER = new(ACE_nothrow) CONSTRUCTOR; \
         if (POINTER == 0) { errno = ENOMEM; } \
       } while (0)

    # else

    #    define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
       do { try { POINTER = new CONSTRUCTOR; } \
         catch (ACE_bad_alloc) { ACE_del_bad_alloc errno = ENOMEM; POINTER = 0; return RET_VAL; } \
       } while (0)

    #    define ACE_NEW(POINTER,CONSTRUCTOR) \
       do { try { POINTER = new CONSTRUCTOR; } \
         catch (ACE_bad_alloc) { ACE_del_bad_alloc errno = ENOMEM; POINTER = 0; return; } \
       } while (0)

    #    define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \
       do { try { POINTER = new CONSTRUCTOR; } \
         catch (ACE_bad_alloc) { ACE_del_bad_alloc errno = ENOMEM; POINTER = 0; } \
       } while (0)
    # endif /* ACE_HAS_NEW_NOTHROW */

    由此看来
    ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL)所做的事情就是构造(new)一个CONSTRUCTOR类型,然后把地址给了POINTER,若构造(new)失败则返回RET_VAL。
    若不要返回值则
    是ACE_NEW(失败直接return)和ACE_NEW_NORETURN(没有return)

    为什么要这么做呢,我想到原因就是省代码,省了相同结构的代码,不过也带来了危险性,你隐藏了new,这是非常危险的事情,甚至是不让这样做的事情,不知道Douglas C.Schmidt博士又有什么见解。

    所以,在你使用ACE_NEW_RETURN、ACE_NEW和ACE_NEW_NORETURN时候,请你注意它们已经new出来了空间,你需要自己去delete掉,否则会内存泄漏了。
    不过有好的方法,用
    auto_ptr,ACE有自己的<ace/Auto_Ptr.h>,我现在还不大清楚它与std::auto_ptr关系,但是看了下<ace/Auto_Ptr.h>源码,是和std::auto_ptr有关系的。
    auto_ptr来帮助你吧,在auto_ptr牺牲的时候它会帮你delete可能会泄漏的内存
        CTest* test;
        ACE_NEW_RETURN(
    test, CTest, -1);
        auto_ptr<
    CTest> p(test );

    收藏到:Del.icio.us