2012-08-13 60 views
2

我想弄清楚使用虛擬析構函數從模塊B中刪除在模塊A中創建的對象是否安全。虛擬析構函數 - 誰調用基礎free()?

當使用MS C++編譯器時,刪除具有虛擬析構函數的對象只會導致一個vtable調用,並在其內部執行調用(即在創建該對象的同一模塊中,即安全)。

問題是:它只是當前的MS實現,還是在某些標準或文檔中有保證,可以安全地依賴?

下面是VS2010的分解虛析構函數調用的例子:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    test *p = new test(); 
008A1030 push  4 
008A1032 call  dword ptr [__imp_operator new (8A20A0h)] 
008A1038 add   esp,4 
008A103B test  eax,eax 
008A103D je   wmain+19h (8A1049h) 
008A103F mov   dword ptr [eax],offset test::`vftable' (8A2100h) 
008A1045 mov   ecx,eax 
008A1047 jmp   wmain+1Bh (8A104Bh) 
008A1049 xor   ecx,ecx 
    __asm int 3; 
008A104B int   3 
    delete p; 
008A104C test  ecx,ecx 
008A104E je   wmain+28h (8A1058h) 
008A1050 mov   eax,dword ptr [ecx] 
008A1052 mov   edx,dword ptr [eax] 
008A1054 push  1 
008A1056 call  edx 
    __asm int 3; 
008A1058 int   3 
    return 0; 
008A1059 xor   eax,eax 
} 
+0

「我試圖弄清楚是否可以安全地使用虛擬析構函數從模塊B中刪除在模塊A中創建的對象。」 - 如果兩個模塊都編譯到相同的ABI,那麼是的。你的問題的其餘部分與此無關。 – hvd 2012-08-13 10:12:28

+0

相同的ABI - 是的。相同的編譯器版本/運行時庫版本 - 不保證。 – 2012-08-13 10:13:45

+2

這是一個不同的問題。混合不同的運行時庫版本是C++標準沒有具體解決的問題,但一般來說,這已經是未定義的(多次違反一個定義規則),所以它的具體實現是否可以工作以及是否受支持。 – hvd 2012-08-13 10:18:59

回答

3

那麼,呼叫者不會知道對象的類型?如果不知道這種類型,呼叫方怎麼會打電話給Derived::operator delete?只有Derived::~Derived可以知道是否必須調用Derived::operator delete而不是通用::operator delete

因此,我們可以推斷出來電者不能撥打::operator delete

不確定是否operator delete後來調用free(),但這是一個細節。

相關問題