Store pointers to member function in the map
Looks fine to me, but for the fact that descrToFuncMap
needs to be declared static
if you intend to initialise it from inside the static function Initialize()
.
If you want to make sure that Initialize()
gets called, and gets called just once, you can use the Singleton pattern. Basically, if you aren't doing multithreading, that just means wrapping descrToFuncMap
inside its own class (called say FuncMap
) with a private constructor that calls Initialize()
. Then you add a static
local variable of type FuncMap
to Processor::Process()
-- because the variable is static
, it persists and is only initialised once.
Example code (I now realise that friend
isn't really necessary here):
class Processor {
private:
typedef double (MyClass::*MemFuncGetter)();
class FuncMap {
public:
FuncMap() {
descrToFuncMap["X"]=&MyClass::GetX;
descrToFuncMap["SomethingElse"]=&MyClass::GetSomethingElse;
descrToFuncMap["RR"]=&MyClass::GetRR;
descrToFuncMap["T"]=&MyClass::GetT;
}
// Of course you could encapsulate this, but its hardly worth
// the bother since the whole class is private anyway.
map<std::string, MemFuncGetter> descrToFuncMap;
};
public:
void Process(Myclass m, string);
};
void Processor::Process(MyClass ms, const std::string& key) {
static FuncMap fm; // Only gets initialised on first call
map<std::string, Getter>::iterator found=fm.descrToFuncMap.find(key);
if(found!=fm.descrToFuncMap.end()) {
MemFuncGetter memFunc=found->second;
double dResult=(ms).*memFunc();
std::cout<<"Command="<<key<<", and result="<<result<<std::end;
}
}
This is not the "true" Singleton pattern as different functions could create their own, separate instances of FuncMap
, but it's enough for what you need. For "true" Singleton, you would declare FuncMap
's constructor private and add a static method, say getInstance()
, which defined the one-and-only instance as a static
variable and returned a reference to that. Processor::Process()
would then use this with
FuncMap& fm = FuncMap::getInstance();
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on June 20, 2022Comments
-
Admin about 2 years
I'd like to map string to an instance member functions, and store each mapping in the map.
What is the clean way of doing something like that?
class MyClass { //........ virtual double GetX(); virtual double GetSomethingElse(); virtual double GetT(); virtual double GetRR(); //........ }; class Processor { private: typedef double (MyClass::*MemFuncGetter)(); static map<std::string, MemFuncGetter> descrToFuncMap; public: static void Initialize(); void Process(Myclass m, string); }; void Processor::Initialize() { descrToFuncMap["X"]=&MyClass::GetX; descrToFuncMap["SomethingElse"]=&MyClass::GetSomethingElse; descrToFuncMap["RR"]=&MyClass::GetRR; descrToFuncMap["T"]=&MyClass::GetT; }; void Processor::Process(MyClass ms, const std::string& key) { map<std::string, Getter>::iterator found=descrToFuncMap.find(key); if(found!=descrToFuncMap.end()) { MemFuncGetter memFunc=found->second; double dResult=(ms).*memFunc(); std::cout<<"Command="<<key<<", and result="<<result<<std::end; } }
let me know if you see a problem with this approach and what are common idioms for that?
Perhaps, I should use if-else-if statement chain, given that I have a limited number of member functions, instead of a confusing map of func pointers
BTW, I found some of the useful info here in the c++-faq-lite
-
Admin over 15 yearswell yea, obviously I would pass string as a const to reference. My question is perhaps, I should use if-statement chain given that I have a limited number of member functions instead of a confusing map of func pointers
-
Admin over 15 yearsyea it is static (fixed it). I like the idea of a private friend class. Would you demonstrate it with an example? Thanks
-
Admin over 15 yearsWhy doesn't it call an overriden function?