Array of derived objects cannot use the derived methods

Viewed 39

Following up on this question C++ inheritence and array I have a question about derived classes and their methods.

Currently I have this base class

class FunctionBlock
{
public:
    uint8_t  IN1 : 1 ;
    uint8_t  IN2 : 1 ;
    uint8_t  IN3 : 1 ;
    uint8_t    Q : 1 ;
} ; 

And several derived classes. These are just three out of many

class And : public FunctionBlock
{
public:
    And()
    {
        IN1 = IN2 = IN3 = 1 ;
    }
    void run()
    {
        Q = IN1 & IN2 & IN3 ;
    }
} ;

class Input : public FunctionBlock
{
public:

    Input( uint8_t _pin )
    {
        pin = _pin ;
        pinMode( pin, INPUT_PULLUP ) ;
    }

    uint8_t pin ;

    void run()
    {
        Q = digitalRead( pin ) ;
    }
} ;

class Output : public FunctionBlock
{
public:
    Output ( uint8_t _pin )
    {
        pin = _pin ;
        pinMode( pin, OUTPUT ) ;
    }

    uint8_t pin ;

    void run()
    {
        digitalWrite( pin, IN2 ) ;
    }
} ;

Every last derived class has a run() method.

I made an array of these derived classes and I initialized them.

FunctionBlock *block[ nBlocks ]; 
  
void setup()
{
    block[0] = & Input(1);
    block[1] = & Input(2);
    block[2] = & Input(3);
    block[3] = & And() ;
    block[4] = & Output(4) ;
}

Until so far everything compiles just fine.

But now the problem. I want to run the run() method of every object in the array. Like I said before every object has it's own run() method.

In the main loop() I try this code

void loop()
{
/***************** UPDATE FUNCTION BLOCKS *****************/
    for( int i = 0 ; i < nBlocks ; i ++ ) block[i] -> run() ;

/***************** UPDATE LINKS *****************/
    block[3]->IN2 = block[1]->Q ;  // this compiles
    block[3]->IN1 = block[0]->Q ;
    block[3]->IN3 = block[2]->Q ;
    block[4]->IN2 = block[3]->Q ;
} ;

And that tosses me the following error.

arduinoProgram:153:55: error: 'class FunctionBlock' has no member named 'run'

     for( int i = 0 ; i < nBlocks ; i ++ ) block[i] -> run() ;

                                                       ^~~

I understand what is happening. The main class does not have a run() method. Only the derived classes do. But the array itself is of the main class FunctionBlocks and thus has no acces to the different run() methods.

My question: Is there a construct in C++ with which an array of objects can get access to methods of derived classes? Like I am trying to do in my example

(I compile this program avr-gcc compiler)

EDIT: Despite my lack of knowdledge about object pointers. I have also resolved the memory problem by first declaring the static derived objects and than create the 'functionBlock'array.

#include "functionBlocks.h"

static Input  b1 = Input(1) ;
static Input  b2 = Input(2) ;
static Input  b3 = Input(3) ;
static Or     b4 = Or() ;
static Delay  b5 = Delay( 3000 ) ;
static Output b6 = Output(13) ;

const int nBlocks = 6 ;

FunctionBlock *block[] =
{
    &b1,
    &b2,
    &b3,
    &b4,
    &b5,
    &b6,
} ;

void setup()
{
}

void loop()
{
    block[3] -> IN1 = block[0] -> Q ;
    block[3] -> IN2 = block[1] -> Q ;
    block[3] -> IN3 = block[2] -> Q ;
    block[4] -> IN2 = block[3] -> Q ;
    block[5] -> IN2 = block[4] -> Q ;

/***************** UPDATE FUNCTION BLOCKS *****************/
    for( int i = 0 ; i < nBlocks ; i ++ ) block[i] -> run() ;
} ;

The program now also actually works.

1 Answers

I tried the following

class FunctionBlock
{
public:
    uint8_t  IN1 : 1 ;
    uint8_t  IN2 : 1 ;
    uint8_t  IN3 : 1 ;
    uint8_t    Q : 1 ;

    virtual void run() ;
} ; 

The virtual keyword seems to do the trick.

Related