dimanche 20 décembre 2015

Is there a way to make a factory without defining a base class in c++?

I work with Qt and one thing that is bothering me is the fact that I have to use QObject to use qRegisterMetaType. I tried to implement the factory method by my own with success but I still need to use an abstract class.

Is it possible to do the same thing without defining a base class (in this case object)?

Working code:

#include <iostream>
#include <string>
#include <map>
#include <typeinfo>
#include <functional>

class object
{
    public:

    virtual ~object(){}

    virtual std::string to_string() = 0;
};

class SomeObject : public object
{
    public:

    SomeObject(){}
    virtual ~SomeObject(){}

    virtual std::string to_string()
    {
        return "I am a type of SomeObject";
    } 
};

class SomeOtherObject : public object
{
    public:

    SomeOtherObject(){}
    virtual ~SomeOtherObject(){}

    virtual std::string to_string()
    {
        return "I am a type of SomeOtherObject";
    } 
};

std::map<std::string, std::function<object*()>> types;

template<typename O>
inline
static void register_type(const std::string & name)
{
    types[name] = [](){ return new O; };
}

static object * get_object(const std::string & object_name )
{
    return types[object_name]();
}

int main()
{
    register_type<SomeObject>("SomeObject");
    register_type<SomeOtherObject>("SomeOtherObject");

    object * some = get_object("SomeObject");
    object * some_other = get_object("SomeOtherObject");

    std::cout << "::" << some->to_string() << std::endl;
    std::cout << "::" << some_other->to_string() << std::endl;

    delete some;
    delete some_other;

    std::cout << "exit" << std::endl;

    return 0;
}

Output (-std=c++11 required):

::I am a type of SomeObject
::I am a type of SomeOtherObject 
exit

Aucun commentaire:

Enregistrer un commentaire