首页 > 解决方案 > 在多重继承中使用 std::unique_ptr

问题描述

我正在编写一个程序来运行两种动物的模拟 - 狼和兔子。在我的代码中,我有虚拟接口类 IAnimal 和名为 Animal 的基类。所以,在代码的一部分中,我需要为我的动物创建新实例,我写了这个:

void Simulation::age_and_multiply_and_die() {
for (auto *animal: animals) {
    if (animal->is_dead()) continue;
    animal->aging();
    if (animal->must_multiply()) {
        switch (animal->get_type()) {
            case Type::Rabbit: {
                spawn_animal(new Rabbit((Animal *) animal, *this));
                break;
            }
            case Type::Wolf: {
                spawn_animal(new Wolf((Animal *) animal, *this));
                ((Wolf *) animal)->hungry_again();
                break;
            }
        }
    }

其中 spawn_animal() 是:

void spawn_animal(IAnimal *animal) {
    animals.push_back(animal);
    Coords pos = animal->get_position();
    field[pos.y][pos.x].push_back(animal);
}

所以,我想摆脱 switch 语句并使用 unique_ptr 来做这样的事情:

class IAnimal {

public:

    virtual Coords get_position() = 0;

    virtual std::unique_ptr<IAnimal> breed() = 0;
...

void Simulation::age_and_multiply_and_die() {
for (auto *animal: animals) {
    if (animal->is_dead()) continue;
    animal->aging();
    if (animal->must_multiply()) {
      IAnimal child = animal.breed();
      if (child)
          animals.push_back(child);
      }
    }

我怎样才能做到这一点?

标签: c++classmultiple-inheritanceunique-ptr

解决方案


您的breed方法返回 a unique_ptr,因此您应该编写调用代码来接收 a unique_ptr

std::unique_ptr<IAnimal> child = animal.breed();

因为unique_ptr不支持复制,move所以在插入数据结构时应该这样做:

if (child)
{
      animals.push_back(std::move(child));
}

注意:您的代码修改了它迭代的容器。这是禁止的,会导致棘手的问题。取而代之的是,创建一个新的vector,将其填充到您的循环中,然后才丢弃旧的vector


推荐阅读