如何将shared_ptr从一个父类转换为另一个父类?

Mat*_*hew 1 c++ inheritance smart-pointers shared-ptr

我正在重新设计游戏引擎以使用smart-pointers。我有一Object门课,所有东西都从那里继承。我有一个可渲染的GameObject,因此它是从IRenderable(定义纯虚拟渲染函数的类)继承的,不是从Object继承的。我有一个RenderSystem应该shared_ptr在场景中容纳所有IRenderable的对象。

我遇到的问题是如何将我的GameObject shared_ptr投射到RenderSystem的IRenderable?

我尝试过的想法:

  • RenderSystem使用GameObject的shared_ptr,但这不起作用,因为这很危险,因为并非所有gameObjects都是可渲染的。
  • 具有IRenderable从Object继承,应该允许我从Object继承。这将意味着IRenderable不再是接口,因为Object包含其他功能。

这完全可以使用原始指针完成,因此,我觉得可以通过智能指针找到某种方法来达到相同的结果

例:

// Object.h
class Object : public enable_shared_from_this<Object> { ... }
// GameObject.h
class GameObject : public Object { ... }
// MeshRenderer.h
class MeshRenderer : public GameObject, IRenderable { 
public:
    void initialize()
    {
         // Not able to cast Object to IRenderable
         RenderSystem::instance().addRenderable(getShared());

         // AND

         // Not able to cast Object to IRenderable

RenderSystem::instance().addRenderable(std::static_pointer_cast<IRenderable>(getShared()));
    }
}
// RenderSystem.h
class RenderSystem 
{
    std::list<std::shared_ptr<IRenderable>> m_renderables;
 public:
    void addRenderable(std::shared_ptr<IRenderable> ptr)
    {
       m_renderables.push_back(ptr);
    }
}

// main.cpp
...
auto meshRenderer = std::shared_ptr<MeshRenderer>();
...
Run Code Online (Sandbox Code Playgroud)

Jon*_*ely 5

您不能static_pointer_cast直接执行从shared_ptr<Object>到的操作,shared_ptr<IRenderable>因为这些类型无关。

但是您可以转换为派生类型,然后允许隐式转换为shared_ptr<IRenderable>

auto p = std::static_pointer_cast<MeshRenderer>(getShared());
std::shared_ptr<IRenderer> q = p;
Run Code Online (Sandbox Code Playgroud)

这将执行从第一个基类到派生类型的显式转换,然后隐式转换为第二个基类。这是静态允许的,因为已知派生类型与两个碱基都相关,但是在不相关的碱基之间不可能直接转换。