'C++ implement class constructs instance of another classes depending on string it consumes

I need to implement one abstract class, three its concrete subclasses, class which goal to create one of this three classes instances and last class executor of three classes. Requirements are c++98, and not to use if/elseif/else to construct class instance, like i did in a Maker class method make Form. What mechanism i need to avoid if / elseif / else?

For example:

test.h

#ifndef TEST_H
#define TEST_H
#include <iostream>

class Executor {
private:
    const std::string name;
public:
    Executor(const std::string &name = "") {};

    const std::string getname() const {return name;}
};

class BForm {
private:
    const std::string _name;
public:
    BForm(const std::string &name = "") : _name(name) {};
    virtual ~BForm() {};

    virtual void execute(const Executor &src) = 0;

    const std::string getname() {return _name;}
    virtual const std::string gettarget() = 0;
};

class Form1 : public BForm{
private:
    std::string _target;
public:
    Form1(const std::string &target = "") : BForm("form1"), _target(target) {};
    virtual ~Form1() {};

    virtual void execute(const Executor &src) {
        std::cout << src.getname() << " exec form1 target:" << _target << std::endl;
    }

    virtual const std::string gettarget() {return _target;}
};

class Form2 : public BForm {
private:
    std::string _target;
public:
    Form2(const std::string &target = "") : BForm("form2"), _target(target) {};
    virtual ~Form2() {};

    virtual void execute(const Executor &src) {
        std::cout << src.getname() << " exec form2 target:" << _target << std::endl;
    };
    virtual const std::string gettarget() {return _target;}
};

class Form3 : public BForm {
private:
    std::string _target;
public:
    Form3(const std::string &target = "") : BForm("form3"), _target(target) {};
    virtual ~Form3() {};

    virtual void execute(const Executor &src) {
        std::cout << src.getname() << " exec form3 target:" << _target << std::endl;
    };
    virtual const std::string gettarget() {return _target;}
};

class Maker {
public:
    BForm *makeForm(const std::string &name, const std::string &target)
    {
        /* need to avoid */
        if (name == "form1")
            return new Form1(target);
        else if (name == "form2")
            return new Form2(target);
        else
            return new Form3(target);
    }
};

#endif

main.cpp

#include "test.h"

int main() {
    Maker maker;
    BForm *form;
    Executor exec("executor");

    form = maker.makeForm("form1", "A");
    std::cout << form->getname() << " " << form->gettarget() << std::endl;
    form->execute(exec);
    delete form;
    return (0);
}



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source