【问题标题】:Conventions for dealing with vectors of std::tr1::shared_ptr处理 std::tr1::shared_ptr 向量的约定
【发布时间】:2013-09-07 07:25:44
【问题描述】:

我已经开始使用 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();
}

这里的 'scene' 显然会增加每个 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&)?

同样,做一个我经常使用的有序地图: 矢量 _scenesArray; 地图_scenesMap;

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

【问题讨论】:

  • 你真的在使用“tr1::shared_ptr”吗?还是您只是使用 Visual Studio,其中 std::shared_ptr 定义在 tr1 命名空间中?
  • 我想SceneManager::scene 应该返回一个Scene&amp;,因为SceneManager(get)scene 都暗示我要处理的资源是Scene
  • 按照 GMan 的想法,如果scene() 直接返回引用,它也会抑制你对引用计数的偏执。您可以确保不使用悬空引用,但这似乎并不难遵守。
  • scene 对象来去匆匆,以至于您需要分布式所有权? SceneManager 似乎是 all Scene 对象的明显所有者,应该持有对象本身,而不是指向对象的指针。

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


【解决方案1】:

这完全取决于用例。

您怀疑使用指针或引用将节省引用计数开销。

...但是...通常开销不足以担心并且:

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

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

如果所有权保留在 SceneManager 中,则返回引用将便于使用该对象并清楚地表达所有权意图。

同样,做一个我经常使用的有序图:vector _scenesArray;地图_scenesMap;

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

【讨论】:

    猜你喜欢
    • 2011-10-29
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    • 1970-01-01
    • 2011-08-01
    • 2012-03-01
    • 1970-01-01
    相关资源
    最近更新 更多