0

我已经开始使用 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; 地图_scenesMap;

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

4

1 回答 1

0

这完全取决于用例。

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

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

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

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

如果所有权保持不变,SceneManager则返回引用将易于使用该对象并清楚地表达所有权意图。

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

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

于 2013-09-03T23:37:23.403 回答