2010-07-11 108 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();