青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

本來想自己總結下operator new相關的,看到周星星同學已經總結得挺全了,直接拿來記錄下(后面綠色部分新加的)。
轉自
http://blog.vckbase.com/bruceteen/archive/2009/05/27/37427.html

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 Foo;

...
delete p;
我們知道,上面的代碼,也就是C++中的new操作符(new operator)大致會做下面的事情:
a.調用operator new, 給對象分配內存
b.調用Foo的構造函數
c.返回指針
...
d. 調用Foo的析構函數~Foo()
e. 調用operator delete釋放內存

更具體的, new operator的行為如下:
對于如下代碼:
    Foo* p = new(arg1,arg2,…… ) Foo(para1, para2, ...);
    ...
    delete p;
編譯器將生成如下代碼:
    調用 p = operator new( size_t 需要的大小,arg1,arg2,…… );  // 分配內存,這里有可能拋出std::bad_alloc,但無須在new operator中捕捉
    如果構造Foo沒有拋出異常                                                    // 即Foo的構造函數后面顯式的聲明了 throw()
        在p指向處構造foo(para1,para2,……);                              // 調用Foo的構造函數
        return p;
    否則
        try
        {
            在p指向處構造Foo(para1,para2,……);
            return p;
        }
        catch(...)
        {
            調用 operator delete( void* p, arg1,arg2,…… );
            throw;
        }
    ...
    調用 Foo的析構函數~Foo();
    調用 operator delete( void* p );

從上面的步驟可以看出:
(1)對于operator new, 我們只要確保第一參數是表示申請內存的大小, 其他參數可以自己隨意重載
(2)只有Foo構造失?。嬙旌瘮祪葤伋霎惓#?,我們的operator delete( void* p, arg1,arg2,…… )才會被調用,否則只會調用operator delete( void* p )

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
}

6. operator new的函數類型:
對我們來說一般有3種是語言要求的標準operator new(plain new, nothrow new, placement new):
void *operator new(std::size_t count) throw(std::bad_alloc);             //一般的版本(plain new)
void *operator new(std::size_t count,  const std::nothrow_t&) throw();    //兼容早版本, new內存分配失敗不會拋出異常(nothrow new)
void *operator new(std::size_t count, void *ptr) throw();  //placement版本(placement new)

上面的方法我們可以這樣調用:
Foo* p = new Foo;
delete p;

Foo* p1 = new(std::nothrow) Foo;
delete p1;

Foo f;
Foo* p2 = new(&f) Foo;
p2->~Foo();

針對數組則是:
void *operator new[](std::size_t count) throw(std::bad_alloc);            
void *operator new[](std::size_t count,  const std::nothrow_t&) throw();    
void *operator new[](std::size_t count, void *ptr) throw();  

可以看到上面函數第一個都是對象空間大小,除了重載C++中operator new的標準類型,另外我們也可以重載其他類型的operator new, 比如
void *operator new(std::size_t count, const string& s) throw(std::bad_alloc);  
void *operator new[](std::size_t count, const string& s) throw(std::bad_alloc); 

然后就可以這樣調用了: string str("abc"); Foo* p = new(str) Foo;

當然,如果我們自己重寫了operator new, 最好我們也重寫operator delete,這樣如果我們的構造函數里拋出異常,我們自己重寫的operator delete會被調用。(當然,如果構造對象成功,最后delete時只會調用operator delete( void* p ))

比如針對上面新加的operator new函數,新加operator delete如下:
void operator delete(void* p, const string& s) throw();
void operator delete[](void* p, const string& s) throw();
可以看到,自己新加的operator delete, 只需確保第一個參數內存指針。

7. new operator和operator new的區別

      new operator就象sizeof一樣是語言內置的,我們不能改變它的含義,它的功能總是一樣的。它要完成的功能分成兩部分。第一部分是分配足夠的內存以便容納所需類型的對象。第二部分是它調用構造函數初始化內存中的對象。new operator總是做這兩件事情,你不能以任何方式改變它的行為。

  我們所能改變的是如何為對象分配內存。new operator調用一個函數來完成必需的內存分配,你能夠重寫或重載這個函數來改變它的行為。new operator為分配內存所調用函數的名字是operator new。

      如果想在堆上建立一個對象,應該用new operator。它既分配內存又為對象調用構造函數。如果你僅僅想分配內存,就應該調用operator new函數;它不會調用構造函數。如果你想定制自己的在堆對象被建立時的內存分配過程,你應該寫你自己的operator new函數,然后使用new operator,new operator會調用你定制的operator new。如果你想在一塊已經獲得指針的內存里建立一個對象,應該用placement new。
      與new operator/operator new相對應的是delete operator/operator delete, 當我們調用delete operator時,實際上包含析構函數調用和通過operator delete釋放內存2個階段。
   我們可以單純的通過operator new 和 operator delete來分配和釋放內存:
    void *buffer = operator new(50*sizeof(char)); // 內存以容納50個char, 沒有調用構造函數
  ...
  operator delete(buffer); // 釋放內存, 沒有調用析構函數

8. operator new的一些原則:
a. 一般不要重寫全局的operator new, 具體可以參考 不要重載全局 ::operator new
b. 如果重載了operator new, 同時提供所有版本(plain new, nothrow new, placement new)
c. 成對的提供new和delete, 即如果重載了operator new, 同時重載operator delete

 

posted on 2012-10-06 22:25 Richard Wei 閱讀(2778) 評論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            一本一道久久综合狠狠老精东影业 | 美女精品在线| 亚洲欧美日韩一区二区三区在线观看 | 欲香欲色天天天综合和网| 国产午夜精品福利| 国产午夜精品理论片a级大结局 | 国产精品xxxxx| 国产欧美一区二区三区另类精品| 国产一级一区二区| 曰本成人黄色| 在线视频日本亚洲性| 亚洲欧美视频在线观看| 久久精品国产2020观看福利| 免费高清在线一区| 亚洲毛片av| 欧美在线观看你懂的| 免费成人av在线| 欧美午夜一区二区三区免费大片 | 国产欧美一区二区三区在线老狼| 国产综合婷婷| 99re8这里有精品热视频免费| 亚洲中无吗在线| 久久激情视频免费观看| 日韩午夜高潮| 亚洲一区二区在线免费观看| 久久另类ts人妖一区二区| 欧美精品久久一区二区| 国产网站欧美日韩免费精品在线观看| 伊人久久婷婷| 亚洲在线视频| 欧美激情精品| 欧美在线播放| 国产精品久久久久久久app| 精品成人一区二区三区| 亚洲综合电影| 亚洲激情在线播放| 欧美亚洲午夜视频在线观看| 欧美精品激情blacked18| 国产女同一区二区| 正在播放亚洲一区| 国产亚洲在线| 亚洲在线成人| 亚洲美女少妇无套啪啪呻吟| 另类人畜视频在线| 国产日产欧产精品推荐色 | 欧美日韩高清区| 黄色资源网久久资源365| 亚洲欧美影音先锋| 99re6热只有精品免费观看| 久久综合一区| 狠狠色丁香婷婷综合| 欧美一区二区三区在线看 | 久久综合五月天婷婷伊人| 亚洲一区二区三区国产| 欧美午夜宅男影院| 中文精品在线| 亚洲久久成人| 欧美成在线观看| 亚洲精品久久久一区二区三区| 你懂的一区二区| 狂野欧美激情性xxxx欧美| 国内自拍一区| 久久综合一区二区| 久久久综合免费视频| 国产欧美成人| 久久先锋资源| 久热国产精品视频| 亚洲国产高清在线观看视频| 欧美成年网站| 欧美高清在线视频| 一区二区三区回区在观看免费视频| 91久久国产综合久久91精品网站| 欧美国产日韩a欧美在线观看| 亚洲精品乱码| 一区二区三区www| 国产色综合天天综合网| 久久国产一区| 美女诱惑黄网站一区| 亚洲一区二区三区中文字幕| 亚洲婷婷综合久久一本伊一区| 欧美大尺度在线| 亚洲图色在线| 亚洲综合成人在线| 激情一区二区三区| 亚洲日本成人在线观看| 国产精品免费观看视频| 久久久久国色av免费看影院| 久久久亚洲国产天美传媒修理工| 91久久在线观看| 一二三四社区欧美黄| 国产欧美日韩视频一区二区| 欧美国产一区二区三区激情无套| 欧美日韩在线看| 久久精品中文字幕一区二区三区| 美女日韩在线中文字幕| 亚洲自拍啪啪| 久久综合福利| 欧美亚洲免费电影| 欧美成人国产va精品日本一级| 亚洲一区二区三区免费观看| 久久www免费人成看片高清| 亚洲福利视频二区| 亚洲香蕉网站| 日韩视频在线免费| 午夜精品一区二区三区四区| 亚洲三级色网| 久久精品论坛| 午夜精品国产更新| 欧美精品福利在线| 久久躁日日躁aaaaxxxx| 国产精品久久久久久妇女6080 | 乱码第一页成人| 国产精品一区在线播放| 亚洲三级视频在线观看| 悠悠资源网亚洲青| 西西裸体人体做爰大胆久久久| 亚洲作爱视频| 欧美国产综合视频| 免费毛片一区二区三区久久久| 国产日本亚洲高清| 亚洲无线一线二线三线区别av| 亚洲毛片在线看| 久久免费黄色| 久久久九九九九| 国产精品久久久久aaaa九色| 91久久夜色精品国产九色| 亚洲高清在线播放| 性久久久久久久久久久久| 亚洲在线观看| 国产精品高潮呻吟| 亚洲免费大片| 一本色道久久综合亚洲精品高清| 欧美成人精品不卡视频在线观看| 久久综合中文色婷婷| 一区二区三区在线视频免费观看 | 亚洲美女视频网| 久久综合伊人| 亚洲高清中文字幕| 91久久久久久久久| 欧美/亚洲一区| 亚洲精品小视频在线观看| 欧美成人午夜剧场免费观看| 精品成人久久| 久久综合久久久| 欧美不卡视频| 亚洲国产福利在线| 麻豆国产精品一区二区三区 | 老司机精品久久| 欧美大色视频| 亚洲精品孕妇| 欧美三日本三级三级在线播放| 亚洲麻豆av| 午夜精品影院在线观看| 国产欧美三级| 久久久久久亚洲综合影院红桃| 久久亚洲国产成人| 亚洲欧洲精品成人久久奇米网 | 欧美日韩一区二区高清| 中国日韩欧美久久久久久久久| 亚洲欧美国产不卡| 国产日产亚洲精品| 久久一区二区精品| 亚洲美女精品成人在线视频| 欧美亚洲专区| 在线观看日韩www视频免费| 欧美精品国产一区| 亚洲女同精品视频| 免费观看在线综合| 中国女人久久久| 狠狠色丁香婷婷综合| 欧美日韩中字| 久久精品国语| 一区二区三区视频在线观看| 久久久久久久999| 日韩午夜av| 国产一区久久久| 欧美久久久久免费| 久久精品国产清高在天天线| 亚洲欧洲一区二区天堂久久 | 亚洲精品久久久久久久久久久久久| 欧美一区二区三区喷汁尤物| 亚洲人永久免费| 国产精品午夜在线观看| 欧美成人国产| 久久精品国产v日韩v亚洲| 日韩一二在线观看| 另类尿喷潮videofree| 亚洲视频axxx| 亚洲区一区二| 影音先锋中文字幕一区| 国产精品久久久久999| 欧美另类视频| 欧美成人a∨高清免费观看| 久久aⅴ国产紧身牛仔裤| 一本色道久久加勒比精品| 噜噜噜躁狠狠躁狠狠精品视频| 亚洲欧美一级二级三级| 国产精品99久久久久久久vr | 久久久久久综合| 羞羞漫画18久久大片|