2012-09-21 107 views
2

Possible Duplicate:
Public operator new, private operator delete: getting C2248 「can not access private member」 when using new私營運營商刪除

http://efesx.com/2009/12/01/public-operator-new-and-private-operator-delete/

在這篇文章中,我讀了這段代碼應該給一個錯誤:

#include <cstdlib> 

struct Try { 
     Try() { /* o/ */ } 

     void *operator new (size_t size) { 
      return malloc(size); 
     } 

    private: 
     void operator delete (void *obj) { 
      free(obj); 
     } 
}; 

int main() { 
    Try *t = new Try(); 

    return 0; 
} 

我用gcc 4.7.1試了一下:

Compilation finished with errors: source.cpp: In function 'int 
main()': source.cpp:11:14: error: 'static void Try::operator 
delete(void*)' is private source.cpp:17:22: error: within this context 
source.cpp:11:14: error: 'static void Try::operator delete(void*)' is 
private source.cpp:17:22: error: within this context source.cpp:17:10: 
warning: unused variable 't' [-Wunused-variable] 

在本文的評論我看到這個鏈接 - Public operator new, private operator delete: getting C2248 "can not access private member" when using new

如果我unserstand它是正確的,它不會編譯,因爲編譯器應該避免在任何情況下,內存泄漏當有異常,通過調用相應的操作員刪除構造函數拋出。但爲什麼這個代碼編譯和工作?

#include <cstdlib> 

struct Try { 
     void *operator new (size_t size) { 
      return malloc(size); 
     } 

    private: 
     void operator delete (void *obj) { 
      free(obj); 
     } 
}; 

int main() { 
    Try *t = new Try; 

    return 0; 
} 

它是由標準或不正確?

又是怎麼回事這個代碼?

#include <cstdlib> 

struct Try { 
     void *operator new (size_t size) { 
      return malloc(size); 
     } 

    private: 
     void operator delete (void *obj) { 
      free(obj); 
     } 
}; 

int main() { 
    Try *t = new Try(); 

    return 0; 
} 

它不能用gcc 4.7.1編譯。

怎麼這樣的事情應該在標準庫來實現?

科莫不會編譯所有這些例子:

"ComeauTest.c", line 15: error: function "Try::operator delete" 
(declared at line 9) is inaccessible Try *t = new Try;^

任何人都可以解釋我對此進行了詳細,好嗎?

+0

答案已鏈接到您在問題頂部的鏈接的評論部分。我把這個問題作爲你的問題的重複。 –

+0

你問爲什麼第一個和第三個例子不編譯,或者爲什麼第二個(使用'new Try'而不是'new Try()')呢? 「重複」只回答其中的第一個。 –

+0

我想知道爲什麼不同的編譯器以不同的方式工作 – FrozenHeart

回答

2
  • 看來,你是對的第一個例子。

第二和第三例子處理POD類型。並有initialization differences發揮作用。

  • 在第二個例子中的結構左初始化。沒有問題出現。

  • 相反,在第三個例子結構確實初始化,所以你得到第一種情況。

編輯:

然後,operator new本身可以拋出一個異常。標準(C++ 11 darft說):

If the new expression terminates by throwing an exception, it may release storage by calling a deallocation function (3.7.4.2). If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete .

它有點不清楚,哪些作者想表達的說這可能釋放存儲空間。這似乎是實現定義的,如果它被釋放

無論如何,你可以嘗試使用不拋new版本:涉及運營商刪除太的情況下,如果你的構造函數代碼拋出一個異常

void *operator new (size_t size, std::nothrow_t) throw() { 
    return malloc(size); 
} 
+0

但是爲什麼不同的編譯器以不同的方式工作? – FrozenHeart

0

編譯器生成構造函數代碼。所以,使用會自動創建使用刪除

在第二個示例編譯器知道您使用默認構造函數不會拋出(我猜測)..

不同的編譯器的工作方式不同CUS他們是不同的(隊長),並有不同的優化能力和技巧,以創建代碼