2013-05-16 50 views
2

我重載操作符new/delete在一個子類中,我注意到一種行爲,這對我來說似乎很奇怪。當使用Visual Studio 2010編譯重載操作符new和匹配刪除

#include <stdlib.h> 
#include <stdio.h> 

class Base 
{ 
public: 

    virtual ~Base() 
    { 
    } 
}; 

class Derived : public Base 
{ 
public: 

    void* operator new(unsigned int size, int capacity) 
    { 
     printf("> new(unsigned int, int)\n"); 
     return malloc(sizeof(Derived)); 
    } 

    void operator delete(void* ptr, int) 
    { 
     printf("> delete(void*, int)\n"); 
     free(ptr); 
    } 

    void operator delete(void* ptr) 
    { 
     printf("> delete(void*)\n"); 
     free(ptr); 
    } 
}; 

int main(int argc, char** argv) 
{ 
    Base* base = new (0) Derived(); 
    delete base; 

    return 0; 
} 

此代碼生成以下的輸出:看看下面的示例代碼

> new(unsigned int, int) 
> delete(void*) 

爲什麼匹配delete操作符(Derived::operator delete(void*, int))沒有得到這裏叫什麼?無論我做什麼,我都無法讓代碼調用匹配的運算符delete。

回答

5

基本的口頭禪:

沒有投放刪除表達。

如果使用放置新創建一個對象,你必須手動銷燬它,然後調用釋放函數:

Base * p = new (0) Derived; 

p->~Derived(); 

Derived::operator delete(p, 0); 

如果你願意,它是那種不確定的行爲說delete base;在代碼,因爲您從未獲得base作爲標準新表達式的結果。完全有可能你定義了一個放置新的分配函數,它完全不同,並且調用標準operator delete分配函數可能會造成巨大的破壞。它恰好在你的程序中運行。