处理std::tr1::shared_ptr向量的约定

Conventions for dealing with vectors of std::tr1::shared_ptr

本文关键字:向量 ptr 约定 shared std tr1 处理      更新时间:2023-10-16

我已经开始使用std::tr1::shared_ptr,到目前为止我很喜欢它。我理解其中的一些陷阱(例如,两个类包含彼此的智能指针成员)。但在其他情况下,我不确定是否使用智能指针。

例如

class Scene;
typedef shared_ptr<Scene> ScenePtr;
Class SceneManager {
public:
   int size() { return _scenes.size(); }
   ScenePtr scene(int i) { return _scenes[i]; }
private:
   vector<ScenePtr> _scenes;
}

这一切都很好,运行得很好。然而,如果我有一个外部控制器,做有什么缺点吗

for(int i=0; i<_sceneManager->size(); i++) {
   ScenePtr scene = _sceneManager->scene(i);
   scene->doSomething();
}

这里的"场景"显然会增加每个ScenePtr的引用计数,但当它超出范围时会再次减少。但是,是否存在任何性能(或任何其他)劣势?

或者,我可以使用普通的C指针

for(int i=0; i<_sceneManager->size(); i++) {
   Scene* scene = _sceneManager->scene(i).get();
   scene->doSomething();
}

但这真的更好吗?还是完全一样?参考人数增加了吗?(在函数调用上),但一离开第一行就减少了?

我过去经常使用参考资料,这会有什么并发症吗?

for(int i=0; i<_sceneManager->size(); i++) {
   Scene& scene = *_sceneManager->scene(i);
   scene.doSomething();
}

最后,返回ScenePtr是个好主意吗?还是SceneManager::scene(i)应该返回(scene*)甚至(scene&)?

同样,为了制作有序地图,我经常使用:vector _scenesArray;地图场景地图;

所以我可以按名称或顺序访问对象。使用std::tr1::shared_ptr时,它们应该都是ScenePtr吗?或者只是其中一个ScenePtr和另一个Scene*?

这一切都取决于用例。

正如您所怀疑的那样,使用指针或引用将节省引用计数开销。

但是通常开销不足以让人担心:

如果sceneManager在多个线程中使用,或者此函数需要重入安全,那么通过共享指针访问的安全性可能是首选。如果你没有使用shared_ptr,你需要以其他方式来确保对象不会被破坏。

返回什么取决于是否要传递对象的所有权。如果对象已经在其他地方的共享指针中,则不能从指针转到shared_ptr。您必须从shared_ptr传递到shared_ptr,否则每个单独的shared_ptrs链都将尝试删除该对象。多次删除=>崩溃。

若所有权保留在SceneManager中,则返回一个引用将使对象易于使用,并清晰地表达所有权的意图。

类似地,为了制作有序映射,我经常使用:vector_scenesArray;地图场景地图;

为了简单和灵活,我会从他们都持有shared_ptr开始。如果以后在应用程序中出现瓶颈的情况,您可以切换c并添加逻辑作为性能优化。