unique_ptr 的 static_pointer_cast 的替代方案 [英] Alternatives of static_pointer_cast for unique_ptr
问题描述
我了解将 static_pointer_cast
与 unique_ptr
结合使用会导致所包含数据的共享所有权.
换句话说,我想做的是:
I understand that using static_pointer_cast
with unique_ptr
would lead to a shared ownership of the contained data.
In other terms, what I'd like to do is:
unique_ptr<Base> foo = fooFactory();
// do something for a while
unique_ptr<Derived> bar = static_unique_pointer_cast<Derived>(foo);
无论如何这样做会导致两个 unique_ptr
不应该同时存在,所以它是被禁止的.
是的,这是有道理的,绝对的,这就是为什么确实不存在像 static_unique_pointer_cast
这样的东西.
Anyway doing that results with two unique_ptr
that should never exist at the same time, so it is simply forbidden.
Right, it makes sense, absolutely, that's why there doesn't exist anything like static_unique_pointer_cast
indeed.
到目前为止,如果我想存储指向这些基类的指针,但我还需要将它们强制转换为某些派生类(例如,想象一个涉及类型擦除的场景),我使用了 shared_ptr
s 因为我上面提到的.
So far, in cases where I want to store pointers to those base classes, but I also need to cast them to some derived classes (as an example, imagine a scenario involving type erasure), I've used shared_ptr
s because of what I've above mentioned.
无论如何,我在猜测对于这样的问题是否有 shared_ptr
的替代方案,或者它们是否真的是这种情况下的最佳解决方案.
Anyway, I was guessing if there are alternatives to shared_ptr
s for such a problem or if they are really the best solution in that case.
推荐答案
原始指针
您的问题的解决方案是获取原始(非拥有)指针并将其强制转换 - 然后让原始指针超出范围并让剩余的 unique_ptr
控制拥有对象的生命周期.
Raw pointers
The solution for your problem is to get the raw (non-owning) pointer and cast it - then just let the raw pointer go out of scope and let the remaining unique_ptr<Base>
constrol the lifetime of the owned object.
像这样:
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.
Unique_pointer_cast
The other option is to use the release()
function of unique_ptr
to wrap it into another 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 的生命周期很重要.
Similar to using raw pointers one can cast the raw pointers and then create a reference out of them by derefering. In this case it is important to guarantee that the lifetime of the created reference does not exceed the lifetime of the unique_ptr.
示例:
unique_ptr<Base> foo = fooFactory();
Derived& bar = *(static_cast<Derived*>(foo.get()));
//do not use bar after foo goes out of scope
这篇关于unique_ptr 的 static_pointer_cast 的替代方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!