#pragma once
#include <string>

const char* ci;

class Object {
 public:
    virtual std::string ToString() const = 0;
    virtual ~Object() {}
};

class apple : public Object {
 public:
    std::string ToString() const {
        return "apple!";
    }
};

class list : public Object {
 public:
    std::string ToString() const {
        return "list";
    }
};


class yai : public Object {
 public:
    std::string ToString() const {
        return "yet another identifier";
    }
};

class dif : public Object {
 public:
    dif() { }
    std::string id_;
    explicit dif(std::string id_) {
        this->id_ = id_;
    }
    std::string ToString() const {
        return id_;
    }
};

class Factory {
 public:
    Object* Create(std::string class_id) {
        if (class_id == "apple!")
            return new apple;
        if (class_id == "list")
            return new list;
        if (class_id == "yet another identifier")
            return new yai;
        else
            return new dif(ci);
    }

    void Register(const std::string& class_id, Object* (*instance_creator)()) {
        ci = class_id.c_str();
    }
};