Search code examples
c++oopc++11inheritancedynamic-cast

Counting elements in a list with different objects given a property


So i got this two classes and i want to count the number of FlowersGarden objects with the specie rose in my list:

class Garden {
private:
    string owner;
    double lenght, width;
public:
    Garden(string ow, double l, double w) {
        this->ownder = ow;
        this->lenght = l;
        this->width = w;
}

class FlowersGarden: public Garden {
private:
    string species;
public:
    FlowersGarden(string ow, double l, double w, string sp):Garden(ow, l, w) {
        this->species = sp;
}
    string GetSpecies()const {return species;};
};

main.cpp

Graden** list;
list = new Garden* [5];
list[0] = new Garden("asdas", 54, 57);
list[1] = new FlowersGarden("tyyty", 98, 87, "rose");
list[2] = new FlowersGarden("asdasd", 578, 212, "sadas");
list[3] = new Garden("uyiyui", 687, 212); 
int count = 0;
for (int i = 0; i < 4; i++)
    if(dynamic_cast<FlowersGarden*>(list[i]))
        if(list[i]->GetSpecies() == "rose")
           count++;

That's only i can think of solving this problem and i'm getting this error: "class 'Garden' has no member named 'GetSpecies'" and i see why, but i don't know another way.


Solution

  • if(dynamic_cast<FlowersGarden*>(list[i]))

    This guard properly verifies the derived type is of type FlowerGarden. However, list[0]->GetSpecies is still using a pointer of type Garden which doesn't have the function you're trying to use.

    You just need to keep the result of the cast and use it to call the function. For example:

    if (FlowersGarden* result = dynamic_cast<FlowersGarden*>(list[i]))
    {
        if (result->GetSpecies() == "rose")
        {
            ...
        }
    }
    

    Note: As @max66 points out in the comments. The code you posted appears to have a typo for the function the the FlowersGarden class, GetSpecie vs GetSpecies.


    Edit:

    I'm not sure what you're trying to do ultimately (regarding your class hierarchy) but I thought it would be apropos to point out virtual functions. If you're in a situation where there is a function that is applicable to all the derived classes then you shuld add it the the base class and make it virtual. By doing this the need to perform a dynamic_cast is unnecessary and dynamic dispatching will call the derived class implementation when called through a base class pointer.

    For example:

    #include <iostream>
    #include <memory>
    
    class Base
    {
    public:
        virtual ~Base() {}
    
        virtual void print() const = 0; // Pure abstract function
    };
    
    class Derived : public Base
    {
    public:
        virtual void print() const override { std::cout << "Derived\n"; }
    };
    
    int main()
    {
        std::unique_ptr<Base> base = std::make_unique<Derived>();
        base->print();
    
        return 0;
    }
    

    Output:

    Derived
    

    Live Example