用指向class :: method的指针数组调用方法

时间:2018-11-20 03:22:10

标签: c++ templates arduino typedef

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

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

此typedef创建methodFunction:

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

但是我看不到如何使ClassName传递给调度。我认为这需要某种形式的模板,但是我对模板还不清楚。

这是我的完整代码(将代码放入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 个答案:

答案 0 :(得分:0)

调度程序应与实例一起调用。

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