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

时间:2012-11-14 21:19:44

标签: c++ c++11 shared-ptr smart-pointers

我有一个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 个答案:

答案 0 :(得分:4)

你声称它不会编译,但是下面的测试为我编译并运行(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);
}

答案 1 :(得分:2)

我打赌你在使用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::shared_ptrstd::make_shared<T>()一起分配,这样可以节省一个动态分配,甚至可以节省一半的共享状态内存开销。您还应该将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));
}