i think there are better ways to do this. in C++ Programming Style cargill show examples of poorly designed classes and how to do them better.
i think your use of a class to exercise function pointers is unnecessary
consider how a single function could simply be passed a button id argument and how unique function can be invoked thru an array of function pointers.
byte pinButs [] = { A1, A2, A3 };
#define N_PINS 3
byte butState [N_PINS];
// -----------------------------------------------------------------------------
void butFunc1 (void) { Serial.println (__func__); }
void butFunc2 (void) { Serial.println (__func__); }
void butFunc3 (void) { Serial.println (__func__); }
void (*butFunc [])(void) = {
butFunc1,
butFunc2,
butFunc3,
};
// -----------------------------------------------------------------------------
void
genericButFunc (
int n )
{
Serial.print ("genericButFunc: ");
Serial.println (n);
}
// -----------------------------------------------------------------------------
void loop ()
{
for (unsigned n = 0; n < N_PINS; n++) {
byte but = digitalRead (pinButs [n]);
if (butState [n] != but) {
butState [n] = but;
delay (10);
if (LOW == but) {
genericButFunc (n);
(*butFunc[n])();
}
}
}
}
// -----------------------------------------------------------------------------
void setup ()
{
Serial.begin (9600);
for (unsigned n = 0; n < N_PINS; n++) {
pinMode (pinButs [n], INPUT_PULLUP);
butState [n] = digitalRead (pinButs [n]);
}
}
here's example code for a state machine that uses a table of function pointers
//
// example state machine
//
#include <stdio.h>
#include "stateMach.h"
// ------------------------------------------------
Status
a (void* a)
{
printf ("%s:\n", __func__);
return OK;
}
// ------------------------------------------------
Status
b (void* a)
{
printf ("%s:\n", __func__);
return OK;
}
// ------------------------------------------------
Status
c (void* a)
{
printf ("%s:\n", __func__);
return OK;
}
// ------------------------------------------------
Status
__ (void* a)
{
printf ("%s:\n", __func__);
return OK;
}
// --------------------------------------------------------------------
#define N_STATE 3
#define N_STIM 2
typedef enum { S0, S1, S2 } State_t;
typedef Status(*Action_t)(void*) ;
State_t smTransitionTbl [N_STATE] [N_STIM] = {
{ S1, S2, },
{ S0, S2, },
{ S2, S1, },
};
Action_t smActionTbl [N_STATE] [N_STIM] = {
{ a, b },
{ c, __ },
{ __, a },
};
// ------------------------------------------------
char *msg1 [] = {
"State machine has 3 states and 2 stimuli.",
"It has the following state transistion and action routine tables.",
"A __() represents do nothing and is easily identified in table.",
"Each row is indexed by a state and each column a stimulus.",
"Of course, meaningful action routine names are helpful.",
};
char *msg2 [] = {
"Enter valid stimuli [0-1]:"
};
void
smHelp (void)
{
for (int i = 0; i < sizeof(msg1)/sizeof(char*); i++)
printf (" %s\n", msg1 [i]);
for (int state = 0; state < N_STATE; state++) {
printf ("%8s", "");
for (int stim = 0; stim < N_STIM; stim++)
printf (" %d", smTransitionTbl [state][stim]);
printf ("%8s", "");
for (int stim = 0; stim < N_STIM; stim++) {
if (a == smActionTbl [state][stim])
printf (" a()");
else if (b == smActionTbl [state][stim])
printf (" b()");
else if (c == smActionTbl [state][stim])
printf (" c()");
else
printf (" __()");
}
printf ("\n");
}
for (int i = 0; i < sizeof(msg2)/sizeof(char*); i++)
printf (" %s\n", msg2 [i]);
}
// ------------------------------------------------
static State_t _smState = S0;
Status
smEngine (Stim_t stim)
{
Action_t func;
State_t last = _smState;
if (N_STIM <= stim)
return ERROR;
func = smActionTbl [_smState] [stim];
_smState = smTransitionTbl [_smState] [stim];
printf (" stim %d, transition from state %d to %d, exec ",
stim, last, _smState);
return (*func) (NULL);
}