在矢量槽参考中包含和修改对象

时间:2018-08-02 15:57:21

标签: c++ reference stdvector

我有这个简单的生物和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无法正常工作?

1 个答案:

答案 0 :(得分:2)

这是由于std::vector增长时它将重新分配其内容而引起的。这意味着对该向量的所有指针和引用都将失效。

您正在Creature类中存储对AI的引用,在您的第一个示例中,该引用变得无效,因为在获得引用后将对象添加到向量中。

在第二个示例中,首先添加所有对象,然后再引用它们。因此,所有引用仍然有效。