#原始指针
解决您的问题的方法是获取原始(非拥有)指针并进行转换 - 然后只需让原始指针超出作用域,让其余的unique_ptr<Base>
控制所拥有对象的生命周期。
像这样:
unique_ptr<Base> foo = fooFactory();
{
Base* tempBase = foo.get();
Derived* tempDerived = static_cast<Derived*>(tempBase);
} // tempBase and tempDerived go out of scope here, but foo remains -> no need to delete
#Unique_pointer_cast
另一个选项是使用unique_ptr
的release()
函数将其包装成另一个unique_ptr。
像这样:
template<typename TO, typename FROM>
unique_ptr<TO> static_unique_pointer_cast (unique_ptr<FROM>&& old){
return unique_ptr<TO>{static_cast<TO*>(old.release())};
// conversion: unique_ptr<FROM>->FROM*->TO*->unique_ptr<TO>
}
unique_ptr<Base> foo = fooFactory();
unique_ptr<Derived> foo2 = static_unique_pointer_cast<Derived>(std::move(foo));
请记住,这会使旧指针foo
失效。
#来自原始指针的参考
仅为回答完整性,该解决方案实际上是在评论中由 OP 提出的原始指针的微小修改。
与使用原始指针类似,可以将原始指针进行类型转换,然后通过取消引用来创建一个引用。 在这种情况下,重要的是确保所创建的引用的生命周期不会超过unique_ptr的生命周期。
示例:
unique_ptr<Base> foo = fooFactory()
Derived& bar = *(static_cast<Derived*>(foo.get()))
// do not use bar after foo goes out of scope
static_pointer_cast
仅适用于类型为std::shared_ptr<T>
的参数 - 它不能与unique_ptr
一起使用。 - M.Munique_ptr
的等价物。 - skypjack*_unique_cast
模板可以为所有四种类型转换编写。 - Caleth