2010-07-11 106 views
13

如果我有一個工廠,創建一個對象,並返回一個指向它,這將是一個更好的方式來刪除它:在哪裏刪除工廠創建的對象?

通過delete通話中的「用戶」的代碼,或由新的DestructObject功能,我應該和工廠一起?

+1

取決於誰擁有一旦創建對象。但是返回一個指針並不是一個好主意,因爲它具有零關聯的所有權語義。 – 2010-07-11 07:39:24

回答

13

在一般情況下,工廠可能不會使用普通舊new來分配對象。它可能會使用對象和/或頁面池,mallocnew,或更奇特的東西(內存映射?)。至少有三種方式來處理這個問題,我能想到的:

  1. 有廠家供應,當你這個對象被稱爲recycle方法。
  2. 返回一個智能指針,知道如何在沒有引用者的情況下取消該對象。
  3. 在對象本身中實現自定義delete運算符。

我不願意推薦一個,因爲在過去的五分鐘內我沒有給出足夠的想法來提供明確的意見,但我傾向於支持最後一個選項與常規智能像boost/tr1 :: shared_ptr這樣的指針。

+0

請注意通過shared_ptr在DLL邊界上傳遞對象。然後使用intrusive_ptr ...我曾經遇到過這個問題,並且破壞了我的希望,即在使用shared_ptr時,您始終處於安全的一邊。 – jdehaan 2010-07-11 07:18:59

+1

@jdehaan:shared_ptr將調用始終位於「安全端」的自定義'delete'。 – 2010-07-11 07:34:59

+0

+1 for boost :: shared_ptr。這是最好的方式。 – 2010-07-11 07:47:31

1

手動刪除它的最好方法是not at all

+2

諷刺不能很好地轉換成任何記錄格式。這是避免它的最好建議,並且要具體而不是隱藏鏈接中的含義。但是,智能指針的+1可能是一種方法。 – 2010-07-11 07:40:44

0

這個問題的最通用的解決方案是從具有虛擬「查殺」功能的基類中派生你的班級。類似這樣的:

class IDisposable { 
public: 
    virtual void Release() = 0; 
}; 

一般認爲,多態對象應該有虛擬析構函數來支持正確的對象清理。但是這是不完整的,因爲它沒有考慮對象的潛在不同內存管理。

另一方面,此方法不需要使用虛擬析構函數。它現在被替換爲Release函數,它可以執行以下操作:調用正確的析構函數並通過適當的方式釋放內存。

照顧對象的destr

兩個:自毀

對象從工廠返回將實現這個「接口」。

1

下面的代碼提供了一個機會,不用考慮誰應該刪除新創建的對象。

class FooFactory 
{ 
public: 
    static std::auto_ptr<Foo> CreateInstance(); 
}; 

// transmit ownership of created object from factory to 'a' variable 
std::auto_ptr<Foo> a = FooFactory::CreateInstance(); 
// using the created object is not required 
FooFactory::CreateInstance();