代码之家  ›  专栏  ›  技术社区  ›  Bob Jones

使用指向类::方法的指针数组调用方法

  •  0
  • Bob Jones  · 技术社区  · 6 年前

    我要调用一个方法,该方法将接受指向类列表的指针作为参数:方法指针:

    void dispatch ( int cmdCount, methodFunction *pointer [] ) {
    ...
    }
    

    此typedef创建methodFunction:

    typedef void ( ClassName::*methodFunction )( char, char );
    

    但我看不出如何使类名成为传递给dispatch的东西。我认为这需要某种形式的模板,但我还不清楚模板。

    这是我的全部代码(将代码放入templatetest.ino和code.h:

        //  Template Test
        #include "code.h"
    
        Dispatcher *dispatcher;
        Example1 ex1;
        Example2 ex2;
    
        void setup() {
            Serial.begin ( 115200 );
    
            ex1.execute ( 'a', '+' );
            ex1.execute ( 'b', '-' );
            ex2.execute ( 'y', '?' );
        }
    
        void loop() {}
    
        <<<<<<<<<< NEW FILE: code.h >>>>>>>>>>>>
    
    #pragma once
    
    class Dispatcher {
    public:
        template<class T>
    
        void dispatch ( T& instance, void(T::*func)(char sel, char act), char def [][2], int cmdCount ) {
            //  Walk through the array containing sel,act pairs.
            //  When we find a match, launch the function from
            //  tPointer with the same index value.
            for (int i = 0; i < cmdCount; i++) {
                char _sel = def [i] [0];
                char _act = def [i] [1];
                if (( sel == _sel ) && ( act == _act )) {
                    ( *T [i] )( sel, act );
                    return;
                }
            }
        }
    };
    
    //  Example 1 Code
    char ex1Array [] [2] = {
        {'a','+'},
        {'a','-'},
        {'b','+'},
        {'b','-'},
    };
    
    class Example1 {
    public:
    
        char *_name = "Template Example 1";
    
        Dispatcher disp;
    
        static const int cmdCount = sizeof ( ex1Array ) / sizeof ( ex1Array [0] );
    
        typedef void ( Example1::*FunctionPointer )( char sel, char act );
    
        //  Function dispatch table
        FunctionPointer cmdMethods [cmdCount] = {
            &Example1::alphaPlus,
            &Example1::alphaMinus,
            &Example1::betaPlus,
            &Example1::betaMinus,
        };
    
        Example1 () {
        }
    
        void alphaPlus ( char sel, char act ) {
            Serial.println ( F ( "Alpha +" ) );
        }
        void alphaMinus ( char sel, char act ) {
            Serial.println ( F ( "Alpha -" ) );
        }
        void betaPlus ( char sel, char act ) {
            Serial.println ( F ( "Beta +" ) );
        }
        void betaMinus ( char sel, char act ) {
            Serial.println ( F ( "Beta -" ) );
        }
    
        void execute ( char sel, char act ) {
            disp.dispatch ( *this, cmdMethods [0], 'a', 'b', ex1Array[0], cmdCount );
        }
    
    };
    
    //  Example 2 
    char ex2Array [] [2] = {
        {'x','?'},
        {'y','?'},
        {'z','?'},
    };
    
    class Example2 {
    public:
    
        char *_name = "Template Example 2";
    
        Dispatcher disp;
    
        static const int cmdCount = sizeof ( ex2Array ) / sizeof ( ex2Array [0] );
    
        typedef void ( Example2::*FunctionPointer )( char sel, char act );
    
        //  Function dispatch table
        FunctionPointer cmdMethods [cmdCount] = {
            &Example2::x,
            &Example2::y,
            &Example2::z,
        };
    
        Example2 () {
        }
    
        void x ( char sel, char act ) {
            Serial.println ( F ( "X" ) );
        }
        void y ( char sel, char act ) {
            Serial.println ( F ( "Y" ) );
        }
        void z ( char sel, char act ) {
            Serial.println ( F ( "Z" ) );
        }
    
        void execute ( char sel, char act ) {
            disp.dispatch ( *this, cmdMethods [0], 'a', 'b', ex2Array [0], cmdCount );
        }
    };
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   AIMIN PAN    6 年前

    应使用实例调用分派。

    template<class T>
    void dispatch(T& instance, void(T::*func)(char, char), char param1, char param2  )
    {
      instance.*func(param1, param2);
    }
    

    呼叫调度:

    dispatch(*this, cmdMethods[0], 'a', 'b');