2015-07-19 22 views
0

的部分12.5/4 [class.free]什麼安置釋放函數被引入?

如果查找的結果是不明確的或不可訪問,或者如果 查找選擇放置釋放函數,程序是 形成不良。

因此,例如,如果我們寫:

class A 
{ 
public: 
    void* operator new (std::size_t count, std::size_t msg, std::size_t mmsg); 
    void operator delete (void* ptr, std::size_t msg, std::size_t mmsg); 
}; 

void* A::operator new (std::size_t sz, std::size_t msg, std::size_t mmsg){ 
    std::printf("global op new called, message = %lu, %lu", msg, mmsg); 
    return std::malloc(sz); 
} 

void A::operator delete (void* ptr, std::size_t msg, std::size_t mmsg){ 
    std::printf("global op new called, message = %lu, %lu", msg, mmsg); 
} 

live example

放置釋放函數將永遠不會被稱爲刪除表達式求值的一部分。因此,詢問他們的介紹是合理的。我們只能通過撥打operator[](void*, std::size_t, std::size_t)的手動電話給他們打電話,但這不方便。

回答

5

放置釋放函數被調用來清理時,構造函數調用一個new -expression評估過程中拋出。此時傳遞給位置分配的信息仍然可用,並且可以再次傳遞給釋放函數。在稍後的某個階段,在new表達式成功後,該信息不可用,因此delete語句使用普通的釋放函數。


本質上,如果解除分配取決於傳遞給放置分配功能的信息,然後用戶代碼負責保持該信息爲成功創建對象。另一種方法可能是指定C++實現如何保留它,以便它可以遵守任何暗示的限制。但這會帶來複雜性,並會違反C++的「不爲人所用」的設計原則。


微軟的MFC類框架曾經有過,他們忘了提供一個放置釋放函數來匹配他們在調試new用於安置分配功能,導致內存泄漏僅在調試版本中的錯誤。愚蠢。