考虑从class D
和class B
sb
std::shared_ptr<B>
实例派生的dynamic_cast<D*>(sb.get())
。在我确认std::shared_ptr<D>
可能成功后,我想从某人那里创建一个合适的dynami_cast<>
。换句话说,我想在shared_ptr之间实现一种std::enable_shared_from_this
。我怎么能以干净的方式做到这一点?一种可能的解决方案是使B从shared_from_this()
派生,并从(铸造)指针使用D
到boost
。但这需要改变B类的定义。是否有更好的想法? {{1}}中有什么内容吗?
答案 0 :(得分:6)
您知道std::dynamic_pointer_cast
吗?
http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast
答案 1 :(得分:3)
正如其他答案所指出的那样,标准库已经提供了你想要的东西,但为了完整起见,实现它很容易:
template<typename To, typename From>
std::shared_ptr<To>
dynamic_pointer_cast(const std::shared_ptr<From>& from)
{
return std::shared_ptr<To>(from, dynamic_cast<To*>(from.get()));
}
这使用别名构造函数创建一个与shared_ptr
共享所有权的不同类型的新from
,因此它们共享相同的引用计数,即使它们拥有不同的指针(在这种情况下是指针)他们拥有的是不同的类型,但指向同一个对象,但这并不一定是真的。)
这不是正确的,因为如果转换失败(返回空指针),你会得到一个存储空指针的shared_ptr
,但是使用非空指针共享所有权。为了解决这个问题,我们需要进行一些小调整:
template<typename To, typename From>
std::shared_ptr<To>
dynamic_pointer_cast(const std::shared_ptr<From>& from)
{
if (auto p = dynamic_cast<To*>(from.get()))
return std::shared_ptr<To>(from, p);
return {};
}
现在,如果转换失败,我们会返回一个空shared_ptr<To>
,这与dynamic_cast<To*>
的行为更匹配。
答案 2 :(得分:1)
请看这里:dynamic_pointer_cast