通过参考在矢量槽中放置和修改对象
Emplacing and modifying object in vector trough reference
我得到了这个简单的生物和 AI 类。目标是将一个 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 无法运行?
这是因为当 std::vector
增长时它会重新分配它的内容。这意味着指向该向量的所有指针和 引用 都将失效。
您正在 AI
class 中存储对 Creature
的引用,并且在您的第一个示例中它变得无效,因为您在获得之后将对象添加到向量中参考资料。
在您的第二个示例中,首先添加所有对象,然后获取对它们的引用。因此,所有参考资料仍然有效。
我得到了这个简单的生物和 AI 类。目标是将一个 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 无法运行?
这是因为当 std::vector
增长时它会重新分配它的内容。这意味着指向该向量的所有指针和 引用 都将失效。
您正在 AI
class 中存储对 Creature
的引用,并且在您的第一个示例中它变得无效,因为您在获得之后将对象添加到向量中参考资料。
在您的第二个示例中,首先添加所有对象,然后获取对它们的引用。因此,所有参考资料仍然有效。