<i id='ziEUs'><tr id='ziEUs'><dt id='ziEUs'><q id='ziEUs'><span id='ziEUs'><b id='ziEUs'><form id='ziEUs'><ins id='ziEUs'></ins><ul id='ziEUs'></ul><sub id='ziEUs'></sub></form><legend id='ziEUs'></legend><bdo id='ziEUs'><pre id='ziEUs'><center id='ziEUs'></center></pre></bdo></b><th id='ziEUs'></th></span></q></dt></tr></i><div id='ziEUs'><tfoot id='ziEUs'></tfoot><dl id='ziEUs'><fieldset id='ziEUs'></fieldset></dl></div>

    <small id='ziEUs'></small><noframes id='ziEUs'>

    • <bdo id='ziEUs'></bdo><ul id='ziEUs'></ul>
      <legend id='ziEUs'><style id='ziEUs'><dir id='ziEUs'><q id='ziEUs'></q></dir></style></legend><tfoot id='ziEUs'></tfoot>

      在映射中存储指向成员函数的指针

      Store pointers to member function in the map(在映射中存储指向成员函数的指针)

      <legend id='HEx54'><style id='HEx54'><dir id='HEx54'><q id='HEx54'></q></dir></style></legend>

      <small id='HEx54'></small><noframes id='HEx54'>

        <tbody id='HEx54'></tbody>

          <bdo id='HEx54'></bdo><ul id='HEx54'></ul>
          <i id='HEx54'><tr id='HEx54'><dt id='HEx54'><q id='HEx54'><span id='HEx54'><b id='HEx54'><form id='HEx54'><ins id='HEx54'></ins><ul id='HEx54'></ul><sub id='HEx54'></sub></form><legend id='HEx54'></legend><bdo id='HEx54'><pre id='HEx54'><center id='HEx54'></center></pre></bdo></b><th id='HEx54'></th></span></q></dt></tr></i><div id='HEx54'><tfoot id='HEx54'></tfoot><dl id='HEx54'><fieldset id='HEx54'></fieldset></dl></div>
            • <tfoot id='HEx54'></tfoot>
                本文介绍了在映射中存储指向成员函数的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

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

                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?

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

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

                推荐答案

                对我来说看起来不错,但事实上 descrToFuncMap 需要声明 static 如果你打算从静态函数 Initialize() 内部初始化它.

                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().

                如果您想确保 Initialize() 被调用,并且只被调用一次,您可以使用单例模式.基本上,如果你不做多线程,那只是意味着用一个调用 Initialize() 的私有构造函数将 descrToFuncMap 包装在它自己的类(称为 say FuncMap)中.然后将 FuncMap 类型的 static 局部变量添加到 Processor::Process() -- 因为该变量是 staticcode>,它会持续存在并且只初始化一次.

                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.

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

                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;      
                    }
                }
                

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

                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();
                

                这篇关于在映射中存储指向成员函数的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                相关文档推荐

                Is Type(::x); valid?(是类型(::x);有效的?)
                Difference between an inline function and static inline function(内联函数和静态内联函数的区别)
                Compilation fails randomly: quot;cannot open program databasequot;(编译随机失败:“无法打开程序数据库)
                Too many initializers error for a simple array in bcc32(bcc32 中的简单数组的初始值设定项过多错误)
                No Member named stoi in namespace std(命名空间 std 中没有名为 stoi 的成员)
                Error using a constexpr as a template parameter within the same class(在同一个类中使用 constexpr 作为模板参数时出错)

                  <small id='azD46'></small><noframes id='azD46'>

                1. <legend id='azD46'><style id='azD46'><dir id='azD46'><q id='azD46'></q></dir></style></legend>
                  • <bdo id='azD46'></bdo><ul id='azD46'></ul>

                      <i id='azD46'><tr id='azD46'><dt id='azD46'><q id='azD46'><span id='azD46'><b id='azD46'><form id='azD46'><ins id='azD46'></ins><ul id='azD46'></ul><sub id='azD46'></sub></form><legend id='azD46'></legend><bdo id='azD46'><pre id='azD46'><center id='azD46'></center></pre></bdo></b><th id='azD46'></th></span></q></dt></tr></i><div id='azD46'><tfoot id='azD46'></tfoot><dl id='azD46'><fieldset id='azD46'></fieldset></dl></div>
                        <tbody id='azD46'></tbody>
                      <tfoot id='azD46'></tfoot>