我的一个应用程序可以从 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
而不是引用。) - dlfshared_ptr
的一个适用场景,它恰好实现了你所说的:不总是假设所有权,并相应地行为。你的布尔标志在shared_ptr
的引用计数器中有一个隐式等价物。另一种可能性是即使类型正确也始终克隆对象,但如果可能的话,提供一种便宜且快速的克隆方法。 - BartoszKP