C++ 在何处删除工厂创建的对象?
如果我有一个工厂,它创建一个对象并返回指向它的指针,那么有什么更好的方法来删除它:C++ 在何处删除工厂创建的对象?,c++,design-patterns,factory,C++,Design Patterns,Factory,如果我有一个工厂,它创建一个对象并返回指向它的指针,那么有什么更好的方法来删除它: 通过delete调用“用户”代码,或通过我应该与工厂一起使用的新DestructObject函数?在一般情况下,工厂可能不会使用普通的旧new来分配对象。它可以使用对象和/或页面池、malloc和placementnew,或者更奇特的东西(内存映射?)。我至少可以想到三种方法来处理这个问题: 让工厂提供一个recycle方法,在处理完对象后调用该方法 返回一个智能指针,该指针知道一旦没有引用,如何删除该对象 在对
通过
delete
调用“用户”代码,或通过我应该与工厂一起使用的新DestructObject
函数?在一般情况下,工厂可能不会使用普通的旧new
来分配对象。它可以使用对象和/或页面池、malloc
和placementnew
,或者更奇特的东西(内存映射?)。我至少可以想到三种方法来处理这个问题:
recycle
方法,在处理完对象后调用该方法delete
操作符我不太愿意推荐一个而不是另一个,因为我在过去的五分钟里没有对它进行足够的思考来提供一个明确的意见,但我倾向于最后一个选项与常规智能指针(如boost/tr1::shared_ptr)结合使用。手动删除它的最佳方法是。解决此问题的最通用解决方案是从具有虚拟“killing”函数的基类派生类。大概是这样的:
class IDisposable {
public:
virtual void Release() = 0;
};
一般认为多态对象应该有虚拟析构函数来支持正确的对象清理。但是,这是不完整的,因为它没有考虑对象的内存管理可能不同
另一方面,此方法不需要使用虚拟析构函数。它现在被Release
函数所取代,该函数同时执行两个功能:调用correct析构函数和通过适当的方式释放内存
处理对象dest
两者:自毁
从工厂返回的对象将实现此“接口”。下面的代码提供了一个机会,让您不用考虑谁应该删除新创建的对象
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();
class工厂
{
公众:
静态std::auto_ptr CreateInstance();
};
//将已创建对象的所有权从工厂传输到“a”变量
std::auto_ptr a=FooFactory::CreateInstance();
//不需要使用创建的对象
FooFactory::CreateInstance();
注意使用共享的ptr在DLL边界上传递对象。使用一个侵入性的ptr然后。。。我曾经遇到过这个问题,这摧毁了我的希望,即当使用shared_ptr时,您总是安全的。@jdehaan:shared_ptr将调用自定义delete
,它总是“安全的”。@Marcelo,感谢您的精确性,也许我遇到的情况可能与Windows下的旧版本boost::shared_ptr有关,该版本带有频繁加载/卸载的插件DLL。几年前我转向了.NET开发。关于侵入式ptr的推进原理已经变得有点不清楚了:。不知道有什么好的理由选择侵入式ptr@jdehaan:问题可能与使用默认的delete
操作符有关,该操作符将调用链接到调用代码中的任何底层内存分配器。如果分配器在任意一侧静态链接(或者只是两个不同的分配器动态链接),那么严重的崩溃即将发生。还要注意,我指的自定义delete
必须编译到库中,所以不能声明inline
@Marcelo,就是这样!如果没有默认的delete
代码,代码运行良好。。。非常感谢您澄清这一点。这取决于对象创建后的所有者。但是,返回指针从来都不是一个好主意,因为它具有零所有权语义。讽刺不能很好地转换为任何记录的格式。这将是最好的建议,避免它和具体的,而不是隐藏在链接的意义。但是+1表示智能指针是一种可能的方法。