一旦使用,整个程序中的智能指针及其依赖关系

Smart pointers and dependency on it in the whole program, once used

本文关键字:指针 智能 关系 依赖 程序      更新时间:2023-10-16

怪物存储:

class MonstersStorage
{
public:
std::weak_ptr<Monster> getMonster(int ID) const;
private:
std::vector<std::shared_ptr<Monster>> monsters;
}

游戏中只有一个怪物存储区。有很多代码使用Monster对象。

我之所以让怪物存储智能指针,只有一个原因——有时需要在其他地方临时存储对Monster的引用,怪物可能会死亡(被删除并从存储中删除)——因此引用必须安全过期。否则我只会使用普通指针。

问题是,在整个游戏中,在使用Monster的每个地方,它都必须是弱指针,而不是简单的引用或指针——因为所有Monster对象都来自一个来源——怪兽存储。

即使是只需要将Monster传递给它们并对其进行一些操作但不保存对它的引用的函数。例如:

getDamageDealedBy(const Monster&);

必须是:

getDamageDealedBy(const std::weak_ptr<Monster>&);

它根据怪物的存储实现获取所有代码。

我的问题是,在这种函数的情况下,我应该只使用*.get()从智能指针接收的简单引用吗,或者在Monster类的情况下,应该在整个程序中使用weak_ptr。

编辑:每次访问怪物时,都会反复使用this.lock()函数,将其转换为shared_ptr

只有一个人能回答这个问题。这个人确切地知道智能指针所拥有的每个对象的作用域和生存期。那就是你。

当引用特定对象的最后一个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引用,因此,在该函数的持续时间内(以及从该函数调用的任何其他函数的持续期间),将始终存在对底层对象至少一个智能引用。只有在somefunction()返回后,monster_ptr才会超出作用域,在此之前,可以保证您将拥有对底层对象的智能引用,并且使用直接的本机指针是安全的。

总之:如果您能够证明在应用程序的某个特定点上,可以保证至少有一个std::shared_ptr引用给定的对象,那么使用普通指针访问该对象是安全的。