unique_ptr 的 static_pointer_cast 的替代方案 [英] Alternatives of static_pointer_cast for unique_ptr

查看:75
本文介绍了unique_ptr 的 static_pointer_cast 的替代方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解将 static_pointer_castunique_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_ptrs 因为我上面提到的.

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_ptrs because of what I've above mentioned.

无论如何,我在猜测对于这样的问题是否有 shared_ptr 的替代方案,或者它们是否真的是这种情况下的最佳解决方案.

Anyway, I was guessing if there are alternatives to shared_ptrs 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_ptrrelease()函数将其包装成另一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆