亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++ new、delete(new[]、delete[])操作符重載需要注意的問題

2020-01-26 15:11:54
字體:
來源:轉載
供稿:網友

new、delete(new[]、delete[])操作符的重載需要注意:

1.重載的 new、delete(或者 new[]、delete[])操作符必須是類的靜態成員函數(為什么必須是靜態成員函數,這很好理解,因為 new 操作符被調用的時候,對象還未構建)或者是全局函數,函數的原型如下:

復制代碼 代碼如下:

void* operator new(size_t size) throw(std::bad_alloc);
// 這里的 size 為分配的內存的總大小
void* operator new[](size_t size) throw(std::bad_alloc);
 
void operator delete(void* p) throw();
void operator delete[](void* p) throw();
 
void operator delete(void* p, size_t size) throw();
// 區別于 new[] 的參數 size,這里的 size 并非釋放的內存的總大小
void operator delete[](void* p, size_t size) throw();

另外,我們可以使用不同的參數來重載 new、delete(或者 new[]、delete[])操作符,例如:

復制代碼 代碼如下:

// 第一個參數仍為 size_t
void* operator new(size_t size, const char* file, int line);
// 此操作符的使用
string* str = new(__FILE__, __LINE__) string;

重載全局的 new、delete(或者 new[]、delete[])操作符會改變所有默認分配行為(包括某個類的分配行為),因此必須小心使用,如果兩個庫都 new 等進行了全局重載,那么就會出現鏈接錯誤(duplicated symbol link error)。而在類中定義的 new、delete(或者 new[]、delete[])操作符只會影響到本類以及派生類。

很多人完全沒有意識到 operator new、operator delete、operator new[]、operator delete[] 成員函數會被繼承(雖然它們是靜態函數)。有些時候,我們只想為指定的類設置自定義的 operator new 成員函數,而不希望影響到子類的工作。《Effective C++ Third Edition》提供了如下的方案:

復制代碼 代碼如下:

void * Base::operator new(std::size_t size) throw(std::bad_alloc)
{
    // 如果大小不為基類大小
    if (size != sizeof(Base))
        // 調用標準的 new 操作符
        return ::operator new(size);
 
    自定義大小為基類大小的分配處理
}

這樣處理的一個前提是:認為子類的大小一定大于父類。

對于 operator new[] 來說,我們很難通過上面的方式檢查到底是父類還是子類調用了操作符。通過 operator new[] 操作符的參數,我們無法得知分配的元素的個數,無法得知分配的每個元素的大小。operator new[] 的參數 size_t 表明的內存分配的大小可能大于需要分配的元素的內存大小之和,因為動態內存分配可能會分配額外的空間來保存數組元素的個數。

2.兼容默認的 new、delete 的錯誤處理方式

這不是個很簡單的事(詳細參考《Effective C++ Third Edition》 Item 51)。operator new 通常這樣編寫:

復制代碼 代碼如下:

// 這里并沒有考慮多線程訪問的情況
void* operator new(std::size_t size) throw(std::bad_alloc)
{
    using namespace std;
 
    // size == 0 時 new 也必須返回一個合法的指針
    if (size == 0)
        size = 1;
 
    while (true) {
 
        嘗試進行內存的分配
 
        if (內存分配成功)
            return (成功分配的內存的地址);
 
        // 內存分配失敗時,查找當前的 new-handling function
        // 因為沒有直接獲取到 new-handling function 的辦法,因此只能這么做
        new_handler globalHandler = set_new_handler(0);
        set_new_handler(globalHandler);
 
        // 如果存在 new-handling function 則調用
        if (globalHandler) (*globalHandler)();
        // 不存在 new-handling function 則拋出異常
        else throw std::bad_alloc();
    }
}

這一些方面是我們需要注意的:operator new 可以接受 size 為 0 的內存分配且返回一個有效的指針;如果存在 new-handling function 那么在內存分配失敗時會調用它并且再次嘗試內存分配;如果不存在 new-handling function 失敗時拋出 bad_alloc 異常。

要注意的是,一旦設置了 new-handling function 內存分配就會無限循環進行下去,為了避免無限循環的發生,new-handling function 必須做以下幾件事中的一件(詳細參考《Effective C++ Third Edition》 Item 49):讓有更多內存可用、設置另一個能發揮作用的 new-handler、刪除當前的 new handler、拋出一個異常(bad_alloc 或者繼承于 bad_alloc)、直接調用 abort() 或者 exit() 等函數。

對于 operator delete 的異常處理就簡單一些,只需要保證能夠安全的 delete 空指針即可:

復制代碼 代碼如下:

void operator delete(void *rawMemory) throw()
{
    // 操作符可以接受空指針
    if (rawMemory == 0) return;
 
    釋放內存
}

多態的問題(詳細參考《ISO/IEC 14882》)

前面談到了 new、delete(new[]、delete[])操作符的繼承,這里額外討論一下多態的問題,顯然我們只需要討論 delete、delete[] 操作符:

復制代碼 代碼如下:

struct B {
    virtual ~B();
    void operator delete(void*, size_t);
};
 
struct D : B {
    void operator delete(void*);
};
 
void f()
{
    B* bp = new D;
    delete bp;  //1: uses D::operator delete(void*)
}

通過上面的例子,我們可以看到,delete 時正確的調用了 D 的 operator delete 操作符。但是同樣的,對于 delete[] 操作符工作就不正常了(因為對于 delete[] 操作符的檢查是靜態的):

復制代碼 代碼如下:

struct B {
    virtual ~B();
    void operator delete[](void*, size_t);
};
 
struct D : B {
    void operator delete[](void*, size_t);
};
 
void f(int i)
{
    D* dp = new D[i];
    delete [] dp;  //uses D::operator delete[](void*, size_t)
    B* bp = new D[i];
    delete[] bp;  //undefined behavior
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩亚洲一区二区| 欧美日本高清视频| 这里只有精品视频| 在线观看国产成人av片| 欧美日韩裸体免费视频| 91精品视频在线看| 国产亚洲在线播放| 精品国产999| 久久综合久久八八| 成人国产精品久久久| 亚洲一区二区免费在线| 色婷婷av一区二区三区在线观看| 亚洲精品视频在线播放| 欧美视频一区二区三区…| 98精品在线视频| 国产精品免费久久久久影院| 亚洲性日韩精品一区二区| 日韩欧美国产成人| 欧美激情精品在线| 亚洲精品中文字幕有码专区| 欧美大尺度在线观看| 国产精品pans私拍| 97精品一区二区视频在线观看| 精品亚洲一区二区三区| 亚洲欧美日韩视频一区| 欧美精品www| 欧美午夜精品在线| 爽爽爽爽爽爽爽成人免费观看| 亚洲一区二区三区久久| 欧美精品xxx| 日韩视频一区在线| 国产在线拍揄自揄视频不卡99| 91亚洲精华国产精华| 国产精品国产亚洲伊人久久| 夜色77av精品影院| 91精品国产综合久久久久久久久| 亚洲第一二三四五区| 91精品国产高清| 色偷偷偷综合中文字幕;dd| 欧美成年人视频网站欧美| 2019日本中文字幕| 日韩免费在线看| 久久成人亚洲精品| 91成人福利在线| 2019中文字幕在线免费观看| 欧美一级大片在线观看| 国产精品人人做人人爽| 欧美性xxxx极品高清hd直播| 91在线视频成人| 日韩av电影免费观看高清| 欧美日韩亚洲一区二区| 精品国产31久久久久久| 国产久一一精品| 热99精品只有里视频精品| 国产精品免费视频久久久| 国产精品ⅴa在线观看h| 欧美性猛交xxxxx免费看| 成人亲热视频网站| 高清欧美性猛交xxxx黑人猛交| 亚洲女人天堂色在线7777| 日韩欧美在线看| 久久天天躁狠狠躁夜夜爽蜜月| 亚州精品天堂中文字幕| 欧美精品精品精品精品免费| 欧美成人精品在线观看| 日韩小视频在线| 欧美性色xo影院| 欧美国产日产韩国视频| 伊人久久久久久久久久| 97色在线观看免费视频| 国产精品久久久久久久久久东京| 亚洲国产天堂久久综合| 欧美性生交xxxxxdddd| 国产精品美女久久久免费| 国产999精品视频| 成人午夜一级二级三级| 国产精品男女猛烈高潮激情| 亚洲女人天堂成人av在线| 日韩电影中文字幕av| 久久视频国产精品免费视频在线| 韩日欧美一区二区| 亚洲第一男人av| 国产在线播放91| 俺去亚洲欧洲欧美日韩| 97av在线视频免费播放| 国产精品久久久久久久av大片| 91社影院在线观看| 亚州成人av在线| 亚洲国产日韩欧美在线99| 欧美精品成人91久久久久久久| 国产成人综合av| 成人久久久久爱| 欧美日韩国产专区| 青青久久av北条麻妃黑人| 欧美老肥婆性猛交视频| 成人精品一区二区三区电影黑人| 4k岛国日韩精品**专区| 精品亚洲国产视频| 亚洲欧美一区二区精品久久久| 国产精品免费久久久久久| 一区二区三区精品99久久| 国产中文字幕亚洲| 亚洲精选中文字幕| 亚洲高清色综合| 欧美性受xxxx黑人猛交| 欧美激情一级欧美精品| 欧美中文字幕在线观看| 午夜精品久久久久久久99热浪潮| 国产精品2018| 国产精品成人va在线观看| 欧美性xxxxxx| 日本精品久久电影| 不卡av电影院| 久久久久久这里只有精品| 亚洲欧洲中文天堂| 日韩av黄色在线观看| 国产精品美女免费视频| 亚洲一区二区三区在线免费观看| 国产日韩精品综合网站| 午夜免费在线观看精品视频| 日韩在线激情视频| 九九热这里只有精品免费看| 日本免费久久高清视频| 欧美高清视频一区二区| 日韩精品中文字幕视频在线| 久久久精品影院| 欧美黑人一级爽快片淫片高清| 78m国产成人精品视频| 亚洲国产精品小视频| 成人免费高清完整版在线观看| 亚洲一区二区三区四区在线播放| 萌白酱国产一区二区| 国内精品一区二区三区四区| 日韩中文字幕网| 在线播放亚洲激情| 国产成人精品久久| 欧美中文字幕在线播放| 国产欧美日韩视频| 成人免费视频97| 伊人久久大香线蕉av一区二区| 色综合久久中文字幕综合网小说| 亚洲精品国产拍免费91在线| 日韩人体视频一二区| 久久久人成影片一区二区三区观看| 久久久久久久久久久成人| 亚洲男女自偷自拍图片另类| 欧美精品xxx| 国产精品小说在线| 亚洲福利视频网| 久操成人在线视频| 欧美插天视频在线播放| 亚洲自拍偷拍色片视频| 色偷偷av亚洲男人的天堂| 国产精品白嫩初高中害羞小美女| 亚洲天堂视频在线观看| 成人网在线免费观看| 777国产偷窥盗摄精品视频| 韩国福利视频一区| 成人美女免费网站视频| 久久香蕉频线观| 国产福利视频一区二区| 色妞一区二区三区| 欧美视频在线免费| 92福利视频午夜1000合集在线观看|