将指针存储在地图中的成员函数中

8 c++ design-patterns callback

我想将字符串映射到实例成员函数,并将每个映射存储在映射中.

这样做的干净方式是什么?

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;      
      }
 }  
Run Code Online (Sandbox Code Playgroud)

如果您发现这种方法存在问题并且常见的习惯用法是什么,请告诉我们?

也许,我应该使用if-else-if语句链,因为我有一个有限数量的成员函数,而不是一个令人困惑的func指针映射

顺便说一下,我在c ++ - faq-lite中找到了一些有用的信息

j_r*_*ker 6

看起来很好,但是如果你想从静态函数内部初始化它,descrToFuncMap需要声明这个事实.staticInitialize()

如果要确保Initialize()调用它,并且只调用一次,则可以使用Singleton模式.基本上,如果你没有进行多线程处理,那只意味着用一个调用的私有构造函数包装descrToFuncMap在它自己的类(称为say FuncMap)中Initialize().然后添加一个static类型的局部变量FuncMapProcessor::Process()-因为变量是static,它仍然存在,且只初始化一次.

示例代码(我现在意识到friend这里不是必需的):

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;      
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是"真正的"Singleton模式,因为不同的函数可以创建自己独立的实例FuncMap,但它足以满足您的需求.对于"true"Singleton,您可以将FuncMap构造函数声明为private并添加一个静态方法,例如getInstance(),将一个唯一实例定义为static变量并返回对它的引用. Processor::Process()然后将使用它

FuncMap& fm = FuncMap::getInstance();
Run Code Online (Sandbox Code Playgroud)