Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ ecosystem simulator (inheritance)

I am a beginner developing an ecosystem in C++. It works like this:

I have PLANTS(not shown here) and ANIMALS on my grid.

If something is an ANIMAL, it is either a CARNIVORE or an HERBIVORE.

I created this hierarchy:

class ANIMAL
{
private:
    int a_CUR_food_lvl; 
    const int a_MAX_food_lvl; 
    const int a_hunger_rate; 

public:

    ANIMAL(int curr, int max, int rate)
        : a_CUR_food_lvl(curr),
        a_MAX_food_lvl(max),
        a_hunger_rate(rate)
    {}

     virtual ~ANIMAL()
     {
        delete this;
     }

    virtual void Move() = 0;
    virtual void Eat() = 0;
    virtual void Evade() = 0;
    virtual void Reproduce() = 0;
    virtual void Die() = 0;
    virtual void Age() = 0;

    virtual int get_a_CUR_food_lvl() { return a_CUR_food_lvl; };
    virtual int get_a_MAX_food_lvl() { return a_MAX_food_lvl; };
    virtual int get_a_hunger_rate() { return a_hunger_rate; };
}; //end ANIMAL class


//#################################################################
class CARNIVORE : public ANIMAL
{
public:

    class WOLF : public ANIMAL
    {
        WOLF()
            : ANIMAL(150, 200, 2)
        {}
    };

    class CHEETAH : public ANIMAL
    {
        CHEETAH()
            : ANIMAL(75, 125, 5)
        {}
    };
}; //end CARNIVORE class


//#################################################################
class HERBIVORE : public ANIMAL
{
public:


    class RABBIT : public ANIMAL
    {
        RABBIT()
            : ANIMAL(150, 200, 2)
        {}
    };


    class SQUIRREL : public ANIMAL
    {
        SQUIRREL()
            : ANIMAL(150, 200, 2)
        {}
    };
}; //end HERBIVORE class

My Problem:

Later down the line, I want to use dynamic_cast to see if one animal is allowed to eat another animal. Specifically, Animal A is only allowed to eat animal B if A is a CARNIVORE and B an HERBIVORE.

Will nesting the classes like I did allow me to check the type of the object later in my programming? I wouldn't want to think this is correct now and have to change it down the line.

Or if there is a better way other than dynamic_cast (a boolean is_carnivore?) should I be using that instead? I'm aiming for the most readable and best OOP practice

like image 945
user3487243 Avatar asked Jul 26 '26 10:07

user3487243


1 Answers

Your nested classes do not at all represent what you want. Do not consider further this construct to address your problem. Instead:

  • WOLF and CHEETAH should inherit from CARNIVORE
  • SQUIRREL and RABBIT shoulr inherit from HERBIVORE

There are then several ways to see if animal *a can eat animal *b another. The simplest approach would be dynamic_cast as you've suggested:

ANIMAL *a, *b; 
...
if (dynamic_cast<CARNIVORE*>(a) && dynamic_cast<HERBIVORE*>(b)) {
     // *a can eat *b
}

But this would not be the best OOP practice. I don't know all your constraints and requirements, but if you want to be state of the art and be able to encode much more complex rules (like strength and health of protagonists, exceptions for some species, etc..) you may be interested in implementing some kind of double dispatch (such as discussed here

like image 61
Christophe Avatar answered Jul 28 '26 00:07

Christophe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!