简体   繁体   中英

Using std::unique_ptr in multiple inheritance

I'm writing a program that runs a simulation with two types of Animals - Wolfes and Rabbits. In my code i have virtual interface class IAnimal, and base class called Animal. So, in one part of code, I need to make new instances of my animals, and I wrote this:

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;
            }
        }
    }

where spawn_animal() is:

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

so, i want to get rid of switch statement and use unique_ptr to make something like this:

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);
      }
    }

how can i do this?

Your breed method returns a unique_ptr , so you should write your calling code to receive a unique_ptr :

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

Because unique_ptr doesn't support copying, you should move it when inserting into your data structure:

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

Note: your code modifies a container it iterates on. This is forbidden and will lead to tricky problems. Instead of that, create a new vector , fill it in your loop, and only afterwards discard the old vector .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM