【发布时间】:2014-08-15 20:11:17
【问题描述】:
我的一个应用程序将极大地受益于std::unique_ptr<T> 的变体,可以将其配置为不总是假定所指向对象的所有权。
考虑以下类层次结构:
class AbstractFoo { ... };
template<typename T> Foo : public AbstractFoo
{
Foo( const AbstractFoo& absFoo ) { ... }
...
};
和一个 API,它标准化每个例程接受 AbstractFoo 并根据需要转换为 Foo<T> 的特定实例。如果对 AbstractFoo 的引用实际上已经是正确派生类型的实例,则只需要 dynamic_cast 并且不需要复制数据。但是,当抽象引用的类型不正确时,需要执行重要的工作来创建请求格式的副本。
我想要的界面如下所示:
template<typename T>
my_unique_ptr<Foo<T>> Convert( AbstractFoo& absFoo )
{
if( Foo<T>* foo = dynamic_cast<Foo<T>*>(&absFoo) )
return my_unique_ptr<Foo<T>>( foo, false );
else
return my_unique_ptr<Foo<T>>( new Foo<T>(absFoo) );
}
void Bar( AbstractFoo& absFoo )
{
my_unique_ptr<Foo<T>> ptr = Convert<T>( absFoo );
...
}
其中make_unique_ptr<T> 类具有类似于std::unique_ptr<T> 的构造函数,但带有一个可选的布尔参数,用于指定指针是否应由智能指针拥有。
对于这种情况,是否有最佳实践解决方案?我宁愿避免返回原始指针,因为如果在手动删除对象之前引发异常,它可能会导致内存泄漏。
【问题讨论】:
-
shared_ptr有用吗? (您要么需要AbstractFoo来实现enable_shared_from_this,要么将shared_ptr传递给Convert而不是引用)。 -
是的,
shared_ptr似乎就是这种情况,它完全按照您的说法行事:并不总是承担所有权,而是采取相应的行为。您的布尔标志在shared_ptr的引用计数器中有一个隐式等效项。其他可能性是即使类型正确也总是克隆对象,但如果可能的话,也许提供一种廉价且快速的克隆方法。 -
@dlf 根据the documentation,您建议的两种方法都要求对象已经由
shared_ptr管理。不幸的是,这非常具有侵入性,我曾希望智能指针的使用仅限于我的库实现中。 -
@JackPoulson 是的,这是真的。如果这会破坏交易,您将需要其他东西(例如 BartoszKP 建议始终创建克隆,但要降低克隆成本)。
-
如何使用带有空删除器的智能指针?
标签: c++ c++11 smart-pointers