How to determine the type of something in a derived class?

132 views Asked by At

I'm making a farming simulator in which I have the base class Produce, which is inherited from by two classes Crops and Animals. Whenever time progresses I am looking to check through my array of Farmland which each have a Produce, and growing the Crops alone. To do this, I am trying to identify the type of the objects in Farmland.

Farmland lands[] = /* ... */;
// ...
Produce b = lands[i].getPlanted();
Produce* ptr = &b;
Crops* crops = dynamic_cast<Crops*>(ptr);

The above is what I have done, and then there is an if statement which occurs if crops != nullptr. This statement is not happening, even though I know that there are crops in lands, and that Produce has a virtual function.

Edit: I've changed getPlanted() to return a pointer to planted, and changed the above code to:

//Produce& b = lands[i].getPlanted();
Produce* ptr = lands[i].getPlanted();
Crops* crops = dynamic_cast<Crops*>(ptr);

But I'm still not having success. crops should be a nullptr if a crop was planted, correct?

Edit 2: Unfortunately I can't use the final keyword as there are some further inherited classes after that, but the Farmland class looks like this:

class Farmland{
    protected:
    bool empty_or_used;
    bool unlocked;
    Produce planted;

    public:
    //constructors
    Farmland();

    //functions
    bool getEmptyOrUsed();
    void setEmptyOrUsed(bool a);
    bool getUnlocked();
    Produce* getPlanted();
    void setUnlocked(bool b);
    void setProduce(Produce newPlanted);

    //destructor

};

I've been looking at examples of downcasting with dynamic_cast and I just can't get mine to work.

1

There are 1 answers

0
Jakkapong Rattananen On

We need add method for determine derived in base class then override in it in derived.

#include <memory>
#include <vector>
#include <iostream>

enum ProduceType{
    animal,
    crop
};
struct Produce{

    virtual ProduceType get_type() const = 0;//this one
};
struct Animal final :  public Produce {

    ProduceType get_type() const override{
        return ProduceType::animal;
    }

    void animal_thing() const {
        std::cout << "animal thing\n";
    }
};

struct Crop final :  public Produce {

    ProduceType get_type() const override
    {
       return ProduceType::crop;
    }

    void crop_thing() const {
        std::cout << "crop thing\n";
    }
};



int main ()
{
    std::vector<std::shared_ptr<Produce>> land;
    land.push_back(std::make_shared<Crop>());
    land.push_back(std::make_shared<Animal>());

    for(auto& ptr : land){//ptr is always std::shared_ptr<Produce> because we define std::vector to store it.
        if(ptr->get_type() == ProduceType::crop){//but we can still access function for get type of derived
            std::static_pointer_cast<Crop>(ptr)->crop_thing();
        }
        if(ptr->get_type() == ProduceType::animal){
            std::static_pointer_cast<Animal>(ptr)->animal_thing();
        }
    }
    return 0;
}