#include <iostream>
#include <vector>

class Base
{
public:
    virtual void show_data() {
        std::cout<<__PRETTY_FUNCTION__<<std::endl;
    }
    virtual ~Base(){}
};

class Derived: public Base
{
public:
    virtual void show_data() override {
        std::cout<<__PRETTY_FUNCTION__<<std::endl;
        std::cout<<"Just derived"<<std::endl;
        std::cout<<"Such useful"<<std::endl;
    }

};

class Special: public Base
{
    public:
        Special(int num, const std::string &data): secret_num(num), secret_data(data)
        {}

        virtual void show_data() override {
            std::cout<<__PRETTY_FUNCTION__<<std::endl;
            std::cout<<"Num: "<<secret_num<<std::endl;
            std::cout<<"Data: "<<secret_data<<std::endl;
        }

        void set_params(int num, const std::string &data){
            secret_num = num;
            secret_data = data;
        }
    private:
        int secret_num;
        std::string secret_data;
};


int main()
{
    std::vector<Base *> objects{
            new Base(),
            new Special(1111, "mheh"),
            new Derived()
    };

    for (const auto &it: objects)
    {
        Special *special = dynamic_cast<Special *>(it);
        if (special != nullptr)
        {
            special->show_data();
            special->set_params(0, "new data");
            special->show_data();
        }
        else
        {
            it->show_data();
        }
        std::cout<<"========="<<std::endl;
    }
    
    for (auto &it: objects){
        delete it;
    }
}