﻿#include <iostream>
#include <vector>

using namespace std;


// klasa bazowa z metodą wirtualną
class Zwierze {
public:
    // dzięki hierarchii dzidziczenia oraz słowu kluczowemu virtual 
    // uzyskujemy właściwość polimorfizmu dynamicznego (późne wiązanie) 
    virtual void przedstawSie() { cout << "jestem zwierzęciem" << endl; };
    // wirtualny destruktor
    virtual ~Zwierze() {};
};

// klasy pochodne z własną definicją metody wirtualnej
class Lew : public Zwierze {
    void przedstawSie() { cout << "Jestem lwem" << endl; };
};

class LewAfrykanski : public Lew {
    void przedstawSie() { cout << "Jestem lwem afrykańskim" << endl; };
};

class Chomik : public Zwierze {
    void przedstawSie() { cout << "Jestem chomikiem" << endl; };
};

class ChomikSyryjski : public Chomik {
    void przedstawSie() { cout << "Jestem chomikiem syryjskim" << endl; };
};


int main()
{
    cout << "Zwierzyniec:\n\n";
    // tworzymy instancje zwierząt na stercie
    Zwierze* zwierze = new Zwierze();
    Zwierze* lew = new Lew();
    Zwierze* chomik = new Chomik();
    Zwierze* lewAfrykanski = new LewAfrykanski();
    Zwierze* chomikSyryjski = new ChomikSyryjski();

    // tablica ze wskaźnikami na kolejne zwierzęta
    vector<Zwierze*> zoo;
    zoo.push_back(zwierze);
    zoo.push_back(lew);
    zoo.push_back(chomik);
    zoo.push_back(lewAfrykanski);
    zoo.push_back(chomikSyryjski);

    // petla po wszystkich wskaźnikach na zwierzęta
    for (auto z : zoo) {
        z->przedstawSie();
    }

    // sprzątamy pamięć
    delete zwierze;
    delete lew;
    delete chomik;
    delete lewAfrykanski;
    delete chomikSyryjski;
    zwierze = nullptr;
    lew = nullptr;
    chomik = nullptr;
    lewAfrykanski = nullptr;
    chomikSyryjski = nullptr;
}
