我已经开始使用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并添加逻辑作为性能优化。