Вызов метода с массивом указателей на class :: method - PullRequest
0 голосов
/ 20 ноября 2018

Я хочу вызвать метод, который будет принимать в качестве аргумента указатель на список классов: указатели на методы:

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 голосов
/ 20 ноября 2018

отправка должна вызываться с экземпляром.

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