如何将 B 派生自 A 的 shared_ptr<A> 转换为 shared_ptr<B>?

How to cast a shared_ptr<A> to shared_ptr<B> where B is derived from A?

我有一个 std::list 容器,其中包含 class A 的共享指针。 我还有另一个 class,比如 B,它是从 A 派生的。

我目前有执行此操作的代码来填充容器:

shared_ptr<B> b = shared_ptr<B>(new B);
container.push_back(b)

这很好用。

问题是,如何取回最初被推回容器的 shared_ptr

执行以下操作

   list<shared_ptr<A> >::iter anIter = myContainer.begin();
   shared_ptr<B> aB = *(anIter);

不编译。我收到错误

Cannot convert 'A * const' to 'B *'

有什么建议吗?

如果您确定已经检索到 B,正如您的问题所暗示的,那么您可以使用 static_pointer_cast<>()

    shared_ptr<B> b = shared_ptr<B>(new B);
    container.push_back(b);
    auto it = container.begin();
    shared_ptr<B> aB = static_pointer_cast<B>(*it);
    aB->showb();

如有疑问,您可以使用dynamic_pointer_cast<>()。但是与传统的 dynamic_cast<>() 一样,只有当您的 类 是多态的 时,这才有效 ,即您拥有**至少一个虚函数:

   container.push_back(make_shared<A>());
   for (auto i = container.begin(); i!=container.end(); i++) {
       shared_ptr<B> spb = dynamic_pointer_cast<B>(*i); 
       if (spb)
           spb->showb();  // at least one virtual function 
       else cout << "the pointer was not to a B"; 
   }

普通指针的原理和static_cast<>()dynamic_cast<>()类似,见dynamic_cast and static_cast in C++。顺便说一下,还有一个 const_pointer_cast<>() 就像 const_cast<>() 一样用于普通指针。

这里是live demo

您可以使用 std::dynamic_pointer_cast

你这样使用它:

std::shared_ptr<Base> basePtr;
std::shared_ptr<Derived> derivedPtr = std::dynamic_pointer_cast<Derived>(basePtr);