好的,经过查看评论后我现在意识到你需要一个适用于unique_ptr
的dynamic_pointer_cast
版本。
记住,unique_ptrs是独一无二的,所以这里是答案:
请注意,这个答案乍一看可能显得不必要地复杂,但我认为重要的是要记住unique_ptr
可以有自定义删除器。如果我们将unique_ptr动态转换成新的unique_ptr,那么删除器也必须跟随转移,但是如果没有插入一个翻译层,传递给新unique_ptr删除器的指针类型会错误。
这段代码不仅动态地将所有权转移到了一个新的指针类型,还连接了正确的反向指针转换,使得当移动到的unique_ptr
最终超出作用域时,该对象可以通过正确的接口由正确的删除器进行删除。
#include <iostream>
#include <memory>
template<class Dest, class Source, class Deleter>
auto
make_proxy_deleter(std::unique_ptr<Source, Deleter>& source)
{
return [original = source.get_deleter()](Dest* p) {
original(dynamic_cast<Source*>(p));
};
}
template<class Dest, class T, class Deleter>
auto
dynamic_cast_unique(std::unique_ptr<T, Deleter>&& source)
{
auto proxy_deleter = make_proxy_deleter<Dest>(source);
auto p = dynamic_cast<Dest*>(source.get());
if (!p) {
return std::unique_ptr<Dest, decltype(proxy_deleter)>(nullptr,
std::move(proxy_deleter));
}
return std::unique_ptr<Dest, decltype(proxy_deleter)>(dynamic_cast<Dest*>(source.release()),
std::move(proxy_deleter));
}
struct A {
virtual ~A() {};
};
struct B {
virtual ~B() {};
};
struct C: A, B {};
using namespace std;
auto main() -> int
{
auto pa = make_unique<C>();
auto pb = dynamic_cast_unique<B>(std::move(pa));
return 0;
}
shared_ptr
时,unique_ptr
没有任何优势,所以为什么要这样做呢? - Baum mit Augenshared_ptr
,它可以进一步与更多的shared_ptr
实例共享。释放其中一个是没有帮助的。我怀疑这就是为什么没有机制来做到这一点的原因。 - Igor Tandetnikunique_ptr
,因为它拥有该对象的所有权。但是如果你手头只有shared_ptr
,那么这个所有权不属于你;其他人也可能共享它,并且你无法从他们那里夺走它。 - Igor Tandetnikshared_ptr
此时只有一个所有者呢? - Andrey Nasonovshared_ptr
应用静态和动态转换时,您将创建一个新的shared_ptr
对象并增加引用计数。但是,您可以直接对unique_ptr.get()
应用转换。 - Andrey Nasonov