我明白使用static_pointer_cast
with unique_ptr
将导致所包含数据的共享所有权。
换句话说,我想做的是:
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
indeed.
到目前为止,如果我想存储指向这些基类的指针,但我还需要将它们转换为一些派生类(例如,想象一个涉及类型擦除的场景),我已经使用shared_ptr
这是因为我上面提到的。
无论如何,我猜测是否有其他选择shared_ptr
对于这样的问题,或者它们是否确实是这种情况下的最佳解决方案。
#原始指针
问题的解决方案是获取原始(非拥有)指针并对其进行强制转换 - 然后让原始指针超出范围并让剩余的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
另一种选择是使用release()
的函数unique_ptr
将其包装到另一个 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 的生命周期非常重要。
Sample:
unique_ptr<Base> foo = fooFactory();
Derived& bar = *(static_cast<Derived*>(foo.get()));
// do not use bar after foo goes out of scope
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)