首页 文章

学习c 11智能指针,它不会让我像指针一样使用隐式转换吗?

提问于
浏览
0

我有一个ISceneNode接口,并从那个SceneNode基类 . 从SceneNode类派生MeshNode,AnimNode,LightNode,CameraNode等...

现在我有一个actor类,它通过一个方法接收一个shared_ptr并将它存储在一个字段中 .

我希望能够做的是将任何std :: shared_ptr或其他派生类发送到接收shared_ptr的函数中 .

使用裸指针,这将是一个隐式转换 .

我想出的解决方案是为每个派生编写一个重载,然后使用dynamic_pointer_cast将其转换为方法 . 那只是讨厌,应该有一个更好的方法 .

有没有办法获得隐式转换,或者一种我不知道的更好的处理方式?处理这个问题的正确方法是什么?

void SomeFunc()
{
    std::shared_ptr<MeshNode> pMeshNode( new MeshNode() );
    gActor.SetNode( pMeshNode );  // won't compile.

    // or do i have to do it like this
    gActor.SetNode( std::dynamic_pointer_cast<ISceneNode> (pMeshNode) );
}

void Actor::SetNode( std::shared_ptr<ISceneNode> pNode )
{
    mpNode = pNode;
}

// or do I have to do it like this?  Making an over load for each derived.
void Actor::SetNode( std::shared_ptr<MeshNode> pMeshNode )
{
    mpNode = std::dynamic_pointer_cast<ISceneNode> (pMeshNode);
}

2 回答

  • 2

    您声称它不会编译,但以下测试编译并运行(VS2012,Clang,G) . 你应该发布你得到的错误,因为它最有可能是别的 .

    #include <memory>
    
    struct IBase {};
    
    struct Derived : IBase {};
    
    void Foo(std::shared_ptr<IBase> p) {}
    
    int main()
    {
        std::shared_ptr<Derived> d;
        Foo(d);
    }
    
  • 4

    我打赌你在使用VS2010?我发现智能指针支持存在一些问题?在具有更好的C 11支持的编译器(例如VS2012,gcc,clang)上,它应该编译正常 . 不过我会建议你一些扩展:

    class Actor {
      std::shared_ptr<ISceneNode> mpNode;
    public:
      void SetNode(std::shared_ptr<ISceneNode> pNode)
      { mpNode = std::move(pNode); }
    };
    
    void SomeFunc()
    {
      gActor.SetNode(std::make_shared<MeshNode>());
    }
    

    使用 std::make_shared<T>() 分配 std::shared_ptr 总是更好,这可以节省一个动态分配,甚至可以节省共享状态内存开销的一半 . 你也应该传递 std::shared_ptr 作为函数的引用,或者至少将它移动到一个新的值,就像我做的那样 . 您还可以考虑使用 std::unique_ptr ,这使得它更有效(没有共享状态内存开销和线程安全引用计数)并使设计更好(清晰的所有权) . 您可以以非常类似的方式使用:

    class Actor {
      std::unique_ptr<ISceneNode> mpNode;
    public:
      void SetNode(std::unique_ptr<ISceneNode> pNode)
      { mpNode = std::move(pNode); }
    };
    
    void SomeFunc()
    {
      gActor.SetNode(std::unique_ptr<MeshNode>(new MeshNode));
    }
    

相关问题