Reputation: 4980
I have a std::map
where key
is string
and I want the value
to be, not an object, but a reference/pointer to a class
which I can instantiate.
std::map<::std::string, ?class_reference?> handlers_;
Once the specific entry is chosen, I want to create instance of the class and execute a member function.
Upvotes: 0
Views: 124
Reputation:
How to get a reference/pointer to a class (not an object)?
Short answer, you can't. Unfortunately, C++ doesn't work that way.
However, to solve your specific problem, you have the option of a factory pattern, which would look something like this:
template <class T>
class factory {
public:
virtual std::unique_ptr<T> createObject() = 0;
};
class base { // some base class common to all the types you are intending to create
};
class foo : public base { // some class you want to create
};
class fooCreator : public fatory<base> {
public:
std::unique_ptr<T> createObject() {
return someUniquePointerToANewObject;
}
}
int main() {
std::map<std::string, std::unique_ptr<factory<base>>> myMap; // because we are creating some bases
myMap["some key"] = new myFooCreator;
// now let's create some new `base`
if(myMap.find("some matching key") != myMap.end()) {
std::unique_ptr<base> myBaseObject = myMap["some matching key"]->createObject();
// use created object
}
return 0;
}
Of course, there are a lot of things that could go wrong here, like if for some reason you push a nullptr
to myMap
. But at least you have an idea of what it looks like now.
Upvotes: 0
Reputation: 388
As others have already mentioned, if you want to create relevant objects via a string (such as class name), you'll need to use factory pattern which can create related objects (same base class). Here's a simple example easy to understand (you just store lambda which returns objects in the map):
#include <map>
#include <string>
#include <functional>
#include <iostream>
class Base {};
class A : public Base{
public:
A() { std::cout << "A ctr" << std::endl; }
};
class B : public Base {
public:
B() { std::cout << "B ctr" << std::endl; }
};
int main() {
std::map<std::string, std::function<Base*()> > m;
m["a"] = []() { return new A(); };
m["b"] = []() { return new B(); };
m["a"]();
m["b"]();
}
Upvotes: 1