1

let say i have 3 class ,ClassA,ClassB,ClassC,all of them Inheritance from classD, and all of them have Constructor that get only one int, i want build a function that get class name in string and a some int, and return new object from class name , are it possible without checking the classname with condition in c++ ?

i dont want to do something like that

if(className == "classA")
 return new ClassA(Num)
else if(className == "classB")
 return new Classb(Num) ....
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
ido kahana
  • 165
  • 2
  • 8
  • 1
    @cad: No, wrong way around... though one could arguably construct a solution from that and some sort of auto type-registration system... if you didn't mind the fact that `typeid(x).name()` is entirely unspecified. – Lightness Races in Orbit Oct 19 '15 at 14:25
  • Standard C++ does not provide any tools for that. You'll have to use platform dependent libraries to search for the symbol table and demangle the names there. – cdonat Oct 19 '15 at 14:25
  • 1
    you need to use factory pattern. – Nandu Oct 19 '15 at 15:05

2 Answers2

2

Generally speaking, if you want to do something like

Base * createObject(string name)
{
    return new <name_as_a_type>();
}

you will need a language with reflection so it is not possible in C++, but it is possible in, e.g., ruby. You can do some weird stuff in c++ if you particulary hate if conditions, though I have no idea why would you do it:

class Base
{
public:
    Base(int v)
    {
        std::cout << "base" << v << std::endl;
    }
};

class Derived : public Base
{
public:
    Derived(int v)
        : Base(v)
    {
        std::cout << "derived" << v << std::endl;
    }
};

class BaseFactory
{
public:
    virtual Base * create(int value)
    {
        return new Base(value);
    }
};

class DerivedFactory : public BaseFactory
{
    Base * create(int value) override
    {
        return new Derived(value);
    }
};

Base * createAwesomeness(string className, int parameter)
{
    static std::map<string, BaseFactory *> _map = {
        {"Base", new BaseFactory()},
        {"Derived", new DerivedFactory()}
    };
    auto it = _map.find(className);
    if(it != _map.end())
        return it->second->create(parameter);
    return nullptr;
}

int main()
{
    auto b = createAwesomeness("Base", 0); //will construct a Base object
    auto d = createAwesomeness("Derived", 1); //will construct a Derived object
    return 0;
}
Community
  • 1
  • 1
SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
2

To follow on what @SingerOfTheFall say:

You want to implement the Factory Design Pattern. There are many options for this, if you do a google seach:

Some have a typed if, as you have it, but others provide you with the ability to add your own factories as needed (the last 2 in the list above).

For a Qt library that implements a Factory look at the Factories in Qtilities

CJCombrink
  • 3,738
  • 1
  • 22
  • 38