Here is a simple example about how to use factory mode to generate different subclasses in CPlusPlus project.

Class:

RulerBase
|
- RulerA
|
- RulerB

RulerFactory:

class RulerFactory
{
//...
std::unordered_map<std::string, InstanceGenerator> m_Generators

The whole project is at the following part.

fac.hpp

#pragma once
#include <unordered_map>
#include <string>
#include <vector>
#include <iostream>

class RulerBase {
public:
    void print(){ std::cout << "This is Ruler Base." << std::endl; };
};

typedef RulerBase* (*InstanceGenerator)();
class RulerFactory
{
public:
    RulerFactory(){}
    ~RulerFactory(){}

    RulerBase* GenerateModule(std::string moduleType)
    {
        auto it = m_Generators.find( moduleType );
        if( it != m_Generators.end() )
        {
            return it->second();
        }

        return nullptr;
    }
    bool RegisterGenerator(std::string moduleType, const InstanceGenerator& funcCreate)
    {
        return m_Generators.insert(std::make_pair(moduleType, funcCreate)).second;
    }

    static RulerFactory & GetInstance()
    {
        static RulerFactory instance;
        return instance;
    }

private:
    std::unordered_map<std::string, InstanceGenerator> m_Generators;
};

#define RULER_FACTORY_REGISTER(RulerClass, RulerClassStr)                   \
namespace RulerFactoryRegistrations {                             \
    RulerFactoryRegistrations<RulerClass> obj##RulerClass(RulerClassStr);  \
}

namespace RulerFactoryRegistrations {
    template <typename T>
    class RulerFactoryRegistrations
    {
    public:
        RulerFactoryRegistrations(std::string type)
        {
            RulerFactory::GetInstance().RegisterGenerator(
                type,
                []() { return static_cast<RulerBase*>(new T()); }
            );
        }
    };
}

main.cpp

#include <iostream>
#include <map>
#include <string>
#include <memory>
#include <unordered_map>
#include "fac.hpp"


class RulerA : public RulerBase {
public:
    void print() { std::cout << "This is RulerA." << std::endl; }
};


class RulerB : public RulerBase {
public:
    void print() { std::cout << "This is RulerB." << std::endl; }
};

// register in manager
RULER_FACTORY_REGISTER( RulerA, "RulerA" );

RULER_FACTORY_REGISTER( RulerB, "RulerB" );

int main() {

    // generate rulers from strings in json.
    RulerA *objA = static_cast<RulerA *>( RulerFactory::GetInstance().GenerateModule( "RulerA" ) );
    RulerB *objB = static_cast<RulerB *>( RulerFactory::GetInstance().GenerateModule( "RulerB" ) );


    if (objA) {
        objA->print();
    }

    if (objB) {
        objB->print();
    }

    return 0;
}

Build and run it.

➜  g++ main.cpp fac.hpp

➜  ./a.out 
This is RulerA.
This is RulerB.
Categories: CPlusPlus

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

Content Summary
: Input your strings, the tool can get a brief summary of the content for you.

X
0
Would love your thoughts, please comment.x
()
x