0

I am trying to wrap my head around using a manager object to loop through the objects in an array and invoke the virtual functions for each object. Here is my code so far, thanks to some very helpful suggestions, it compiles but still doesn't make use of polymorphism the way that I want it to. Thanks in advance for any tips that can point me in the right direction.

#include <iostream>

class avian{
private:
    static const int max_birds = 25;
    avian* birds[max_birds];
    int num_birds;
public:
    avian() : num_birds(0){}

    virtual ~avian() {
        for (int i = 0; i < num_birds; ++i) { delete birds[i]; }
    }

    bool add(avian* b){
        if (num_birds >= max_birds){ return false; }

    birds[num_birds++] = b;
    return true;
    }

    void make_bird(){
        for (int i = 0; i< num_birds; ++i){birds[i]->make_bird();
        }
    }

    virtual void lay_eggs(){} ;

    virtual void bird_noise(){} ;

};

class turkey : public avian{
public:
    void lay_eggs() const{ std::cout << "000\n"; }
    void bird_noise() const { std::cout << "Gobble Gobble Gobble!\n"; }
};

class chicken : public avian {
public:
    void lay_eggs() const { std::cout << "OOOOO\n"; }
    void bird_noise() const { std::cout << "Bock Bock Bock!\n"; }
};

class quail : public avian{
public:
    void lay_eggs() const { std::cout << "ooooooooo\n"; }
    void bird_noise() const { std::cout << "Chirr Chirr Chirr!\n"; }
};

int main(){
    avian* my_turkey = new turkey;
    my_turkey->make_bird();

    my_turkey->lay_eggs();
    my_turkey->bird_noise();

    delete my_turkey;
    return 0;
}
Vadim Kotov
  • 7,103
  • 8
  • 44
  • 57
cheovy
  • 9
  • 3
  • The compiler is telling you *"deleting object of polymorphic class type `avian` which has non-virtual destructor might cause undefined behaviour"*. Did you try adding a virtual destructor to the class `avian`? – Jon Dec 11 '15 at 23:04
  • Yep. Just changed that. Now it compiles. But it still isn't giving me any output from my virtual functions. – cheovy Dec 11 '15 at 23:21

2 Answers2

2
  1. You don't have a virtual base class destructor:

    virtual ~avian() { ... }
    

    Calls to delete pointer_to_avian will will call avian::~avian, but they will not propagate to the destructors of derived classes - UB, as compiler says.

  2. avian::lay_eggs is declared, but not defined. Did you mean to make it pure virtual function? You've overriden it in every derived class.

  3. avian::bird_noise - same as above
  4. You forgot to delete my_turkey in main - you're leaking memory.
Community
  • 1
  • 1
LogicStuff
  • 18,687
  • 6
  • 49
  • 70
  • 1
    Ok. I changed the destructor and made the two functions pure virtual functions. That cleared up all my errors. Thanks so much for the help! – cheovy Dec 11 '15 at 23:10
  • Ok, I added the delete. I'm somewhat lost on how to implement the polymorphism. I want to use my virtual functions with my derived classes, but I'm not putting the pieces together right. – cheovy Dec 11 '15 at 23:24
  • So then should I add a destructor to each class (i.e. ~turkey)? – cheovy Dec 11 '15 at 23:37
  • @cheovy But why are you storing birds for each bird? That's an anomaly... Those destructors are not required, compiler will generate them. – LogicStuff Dec 11 '15 at 23:37
  • What I am trying to do is have a manager class that stores an array of pointers to "avian" and adds my birds to the array while tracking how many have been added. – cheovy Dec 11 '15 at 23:46
  • Then make `birds` and `num_birds` `static`, too. There must be only one instance of them for every `avian`. Then you cannot delete them in the `avian`'s destructor, you'll need some `static` function. Or, maybe you're just looking for `std::vector`. – LogicStuff Dec 11 '15 at 23:48
  • I think you're right, a vector would be easier to use than what I've got going with this manager class. I'm going to play around with that for a bit. Thanks again for all your advice! – cheovy Dec 11 '15 at 23:57
1

Your base virtual methods are not marked as const. But methods in derived classes are const. So they are not overriden.

Rule of thumb is to use override keyword in order to avoid such errors

Ivan Fateev
  • 952
  • 1
  • 8
  • 23