error: 'X' has no member named 'Y'

Ok so this is a common error, yet I'm unable to understand why this is happening in the program, follow the example :

Arduino Sketch

#include <Arduino.h>
#include <string.h>
#include "Thread.h"
#include "ThreadController.h"

[b]#include <Classe_Indice.h>[/b]
[b]#include <Programas.h>[/b]

Classe_Indice *indice = new Classe_Indice(); // this pointer to object will acess the non-static //methods, it is a global one.

ThreadController cpu;
Programas programacao = Programas();

void setup() {

programacao.setInterval(200);
programacao.onRun(indice->verificaProgramacao);
cpu.add(&programacao);


}


void loop () {

cpu.run()

}

Classe_Indice.h

#ifndef CLASSE_INDICE
#define CLASSE_INDICE

#include <Arduino.h>

class Classe_Indice {
  
    public : int incrementaEvento;
             int incrementaFert;
             void setNumeroEvento(int numeroEvento);
             int getNumeroEvento();
             void setNumeroFert(int numeroFert);
             int getNumeroFert();
    
    private : int numeroEvento;
              int numeroFert;  
    
};



#endif

Classe_Indice.cpp

 /*
 * Method Name  : incrementaFert
 *
 * Synopsis     : int Classe_Indice::incrementaFert()  *
 * Description  : Método que incrementa a variável de indice numeroFert.
 *
 */
 int Classe_Indice::incrementaFert(){
     numeroFert++;
 }
 
 /*
 * Method Name  : setNumeroFert
 *
 * Synopsis     : void Classe_Indice::setNumeroFert(int numeroFert)  *
 * Description  : Método set da variavel de indice numeroFert.
 *
 */
 
 void Classe_Indice::setNumeroFert(int numeroFert){
     _numeroFert = numeroFert;
 }
 
 /*
 * Method Name  : getNumeroFert
 *
 * Synopsis     : int Classe_Indice::getNumeroFert()  *
 * Description  : Método get da variavel de indice numeroFert.
 *
 */
 int Classe_Indice::getNumeroFert(){
     return _numeroFert;
 }
 
 
 
 /*
 * Method Name  : incrementaEvento
 *
 * Synopsis     : int Classe_Indice::incrementaEvento()  *
 * Description  : Método que incrementa a variável de indice numeroEvento.
 *
 */
 int Classe_Indice::incrementaEvento(){
     numeroEvento++;
 }
 

 /*
 * Method Name  : setNumeroEvento
 *
 * Synopsis     : void Classe_Indice::setNumeroEvento(int numeroEvento)  *
 * Description  : Método set da variável de indice numeroEvento.
 *
 */ 
 void Classe_Indice::setNumeroEvento(int numeroEvento){
     _numeroEvento = numeroEvento;
 }
 
 
  /*
 * Method Name  : getNumeroEvento
 *
 * Synopsis     : int Classe_Indice::getNumeroEvento()  *
 * Description  : Método set da variável de indice numeroEvento.
 *
 */ 
 int Classe_Indice::getNumeroEvento(){
     return _numeroEvento;
 }

Programas.h

#ifndef PROGRAMAS_H
#define PROGRAMAS_H

/*Biblioteca padrão do Arduino*/
#include <Arduino.h>

/*Biblioteca de Threads*/
#include "Thread.h"
#include "ThreadController.h"

/* Bibliotecas de data/hora para módulo DS1307 RTC */
#include <Wire.h>
#include <RTClib.h>
#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>

/*Biblioteca de Lista Encadeada*/
#include <LinkedList.h>

#include <Classe_Indice.h>
#include <Fertilizantes.h>
#include <Eventos.h>
#include <Agendamentos.h>
#include <RecuperaIrriga.h.> 
#include <RecuperaFerti.h>

class Programas: public Thread
        {
            public :   bool shouldRun();
                       void verificaProgramacao();
                       
            private :  unsigned long tempo;
                       DateTime now;
                       
                       
        };


#endif

Programas.cpp

#include <Programas.h>

extern LinkedList<Agendamentos*> agendamentos;
extern Programas programacao;
extern RecuperaIrriga thread_prepara_irriga;
extern RecuperaFerti thread_prepara_ferti;
extern RTC_DS1307 rtc;


 
 /*
 * Method Name  : shouldRun
 *
 * Synopsis     : bool Programas::shouldRun()  *
 * Description  : Método que avalia se a Thread deve ser iniciada.
 *
 */
 
 bool Programas::shouldRun(){
    
    unsigned long tempo = 0;   
    DateTime now = rtc.now();
    if (millis() >= 500){    
        if(agendamentos.size() > 0){
            if(((now.dayOfTheWeek()*86400)+(now.hour()*3600)+(now.minute()*60)+(now.second())) == (agendamentos.get(0)->getDia()*86400)+(agendamentos.get(0)->getHora()*3600)+(agendamentos.get(0)->getMinuto()*60)+(agendamentos.get(0)->getSegundo())){
                programacao.run();
                return true;
            }
            else {
                return false;
            }
        }else{
            tempo = millis();
        }
    }    
}



 /*
 * Method Name  : verificaProgramacao
 *
 * Synopsis     : void Programas::verificaProgramacao()  *
 * Description  : Método que inicia a thread e executa suas instruções.
 *
 */

void Programas::verificaProgramacao(){
    


Classe_Indice::numeroEvento = 0;
indice->setNumeroEvento(numeroEvento);


if (agendamentos.get(0)->getEvento(indice->getNumeroEvento())->sizeFertilizantes() == '0'){

    // Irrigacao?
    programacao.enabled = false;
    thread_prepara_irriga.enabled = true;

    } else {

    // E fertirrigacao?
    programacao.enabled = false;
    thread_prepara_ferti.enabled = true;

    }    
}

error: 'class Classe_Indice' has no member named 'verificaProgramacao', note that Programas.h has #include <Classe_Indice.h>, why this is happening? Thanks

rezik:
error: 'class Classe_Indice' has no member named 'verificaProgramacao', note that Programas.h has #include <Classe_Indice.h>, why this is happening? Thanks

Could you show me the member 'verificaProgramacao' the compiler is missing?

class Classe_Indice {
  
    public : int incrementaEvento;
             int incrementaFert;
             void setNumeroEvento(int numeroEvento);
             int getNumeroEvento();
             void setNumeroFert(int numeroFert);
             int getNumeroFert();
    
    private : int numeroEvento;
              int numeroFert;  
    
};
programacao.onRun(indice->verificaProgramacao);

You are passing the address of the function verificaProgramacao(), which you say is a member of the class that indice is an instance of, to this function.

As Whandall points out, verificaProgramacao() is not a member of the Classe_Indice class.

It IS a member of the Programas class:

class Programas: public Thread
        {
            public :   bool shouldRun();
                       void verificaProgramacao();

But, there is no (apparent) relationship between the Classe_Indice class and the Programas class. So, why do you think that verificaProgramacao() should be available to instances of the Classe_Indice class?

Thanks for the reply.

PaulS:

programacao.onRun(indice->verificaProgramacao);

You are passing the address of the function verificaProgramacao(), which you say is a member of the class that indice is an instance of, to this function.

As Whandall points out, verificaProgramacao() is not a member of the Classe_Indice class.

It IS a member of the Programas class:

class Programas: public Thread

{
            public :  bool shouldRun();
                      void verificaProgramacao();




But, there is no (apparent) relationship between the Classe_Indice class and the Programas class. So, why do you think that verificaProgramacao() should be available to instances of the Classe_Indice class?

Indeed verificaProgramacao is not declared among <Class_Indice.h>. I thought that by adding "#includes" would give me that relationship. So what should I do then ? Declare both classes as Friends ? or extend like

class Classe_Indice : public Programas {

};

or extend like

Yes.

By extending it (and also adding include) I receive this :

error: invalid use of non-static member function

  • programacao.onRun(indice->verificaProgramacao);*

I need this method to be non-static by the way. Thanks for your support.

I need this method to be non-static by the way.

Which method? onRun()? Or verificaProgramacao()?

Note that in Classe_Indice.h I'm extending Programas... I've made this because I was getting the following error: 'class Classe_Indice' has no member named 'verificaProgramacao'. Then the problem changed to invalid use of void expression.. changing the synthax to programacao.onRun((*indice->verificaProgramacao())), I'll get : error: void value not ignored as it ought to be[/i
I need verificaProgramacao(), to be non static.

rezik:
verificaProgramacao(), to be non static.

But it seems that Thread::onRun does not want a pointer to a Programas member function.

You will have to supply an acceptable parameter to onRun (I guess a void func(), but I don't know the definition of your Thread class).

Whandall:
But it seems that Thread::onRun does not want a pointer to a Programas member function.

You will have to supply an acceptable parameter to onRun (I guess a void func(), but I don't know the definition of your Thread class).

Take a look at line 83 of this ArduinoThread/Thread.h at master · ivanseidel/ArduinoThread · GitHub

void onRun(void (*callback)(void));

So what?

My guess was correct?

What type do you try to pass to onRun?
What type should the parameter have?

Problem fixed. I changed the methods to static and erased that Class_Indice.h , the variables which where declared within it now are global declared int *numeroEvento and int *numeroFert, whenever I want to use them I pass them by memory adress &numeroEvento or &numeroFert. No compiling errors anymore, this does not mean that program will be executed properly but its already an enhancement. Thanks for the support !

You don't answer questions out of what reason?

Whandall:

void onRun(void (*callback)(void));

So what?

My guess was correct?

What type do you try to pass to onRun?
What type should the parameter have?

Probably your guess was correct, I did not force to pass a non-static function to onRun() anymore,since all my attempts failed.

programacao.onRun(Programas::verificaProgramacao); Worked just fine. Note that verificaProgramacao is void type and it has no parameter.

Have you got all the answers you seek ? Feel free to ask, we're here to share ;D

rezik:
Have you got all the answers you seek ? Feel free to ask, we're here to share ;D

My questions were aimed to let you understand why your approach has to fail.

I learn a lot here, but by helping and reading, not by asking. :wink: