怪物的存放:
class MonstersStorage
{
public:
std::weak_ptr<Monster> getMonster(int ID) const;
private:
std::vector<std::shared_ptr<Monster>> monsters;
}
游戏中只有一个怪物仓库。有很多代码使用 Monster
对象。
我让怪物的存储空间存储智能指针只有一个原因 - 有时需要在其他地方临时存储对 Monster
的引用,并且怪物可能会死亡(被删除并从存储中移除) - 因此引用必须安全地过期。否则我只会使用普通指针。
问题是,在整个游戏中,在每个使用Monster
的地方,它都必须是弱指针,而不是简单的引用或指针——因为所有的Monster
对象来自一个来源 - Monsters Storage。
即使函数只需要将 Monster
传递给它们并对其进行一些操作但不保存对它的引用。例如:
getDamageDealedBy(const Monster&);
它必须是:
getDamageDealedBy(const std::weak_ptr<Monster>&);
它根据怪物的存储实现获取所有代码。
我的问题是,如果是这样的函数,我应该只使用简单的引用,由 *.get() 从智能指针接收,
或者如果是 Monster
类,应该在整个程序中使用 weak_ptr。
编辑:每次都一遍又一遍地使用这个 .lock() 函数,将其转换为 shared_ptr,同时访问 monster
最佳答案
只有一个人知道这个问题的答案。这是确切知道智能指针拥有的每个对象的范围和生命周期的人。那就是你。
当引用特定对象的最后一个 std::shared_ptr
超出范围时,该对象将被销毁。如果,根据您的应用程序使用这些对象的方式,如果您的应用程序的某些其他部分正在使用常规的“非智能”指针来引用该对象,那么这永远不会发生,那么,当然,只使用常规的就可以了指针。
例如,在这种情况下您知道使用普通指针是安全的。
void somefunction(const std::shared_ptr<Monster> &monster_ptr)
{
Monster *p=monster_ptr.get();
// ... Use p inside this function
}
因为 std::shared_ptr
作为参数传递给 somefunction()
,并且 monster_ptr
的范围存在于整个 somefunction()
仅使用 get()
并在此函数内使用返回的指针是安全的。
您知道 monster_ptr
将在此函数的持续时间内存在。因此,monster_ptr
将保留对底层对象的 std::shared_ptr
引用,因此对于此函数的持续时间(以及从此函数调用的任何其他函数的持续时间)。 monster_ptr
仅在 somefunction()
返回后才会超出范围,在此之前,可以保证您将拥有对底层对象的智能引用,并且它是可以安全地使用直接 native 指针。
结论:如果您能证明在您的应用程序的特定点上,可以保证至少有一个 std::shared_ptr
引用给定对象,那么使用普通指针是安全的访问此对象。
关于c++ - 智能指针及其在整个程序中的依赖,一次使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37363625/