我有这个简单的生物和AI类。目标是将AI插入生物并为其提供参考。
生物
class Creature
{
public:
explicit Creature(std::string&& name) : m_name(name) {}
void setAI(std::shared_ptr<AI>&& behavior)
{ m_behavior = std::move(behavior); }
void greet() { m_behavior->action(); }
const std::string& getName() const { return m_name; }
private:
std::shared_ptr<AI> m_behavior;
std::string m_name;
};
AI
class AI
{
public:
explicit AI(Creature& creature) : m_creature(creature) {}
void action() { std::cout << m_creature.getName() << std::endl; }
private:
Creature& m_creature;
};
现在,根据我创建生物并设置AI时的操作顺序,我会得到不同的结果,并且无法理解为什么。
示例1:不起作用。只有最后一个生物具有有效的AI。
std::vector<Creature> atlas;
Creature& quokka = atlas.emplace_back(Creature("Quokka"));
quokka.setAI(std::make_shared<AI>(quokka));
Creature& wombat = atlas.emplace_back(Creature("Wombat"));
wombat.setAI(std::make_shared<AI>(wombat));
Creature& bilby = atlas.emplace_back(Creature("Bilby"));
bilby.setAI(std::make_shared<AI>(bilby));
for (Creature& creature : atlas) { creature.greet(); }
示例2:效果很好
atlas.emplace_back(Creature("Quokka"));
atlas.emplace_back(Creature("Wombat"));
atlas.emplace_back(Creature("Bilby"));
for (Creature& creature : atlas)
{
creature.setAI(std::make_shared<AI>(creature));
}
区别在哪里,为什么示例1无法正常工作?
答案 0 :(得分:2)
这是由于std::vector
增长时它将重新分配其内容而引起的。这意味着对该向量的所有指针和引用都将失效。
您正在Creature
类中存储对AI
的引用,在您的第一个示例中,该引用变得无效,因为在获得引用后将对象添加到向量中。
在第二个示例中,首先添加所有对象,然后再引用它们。因此,所有引用仍然有效。