如何在shared_ptr之间实现类似“dynamic_cast”的运算符?

时间:2014-03-12 13:49:47

标签: c++11 shared-ptr dynamic-cast

考虑从class Dclass 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()派生,并从(铸造)指针使用Dboost。但这需要改变B类的定义。是否有更好的想法? {{1}}中有什么内容吗?

3 个答案:

答案 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