Bonjour, cliquez-ici pour vous inscrire et participer au forum.
  • Login:



+ Répondre à la discussion
Page 1 sur 2 1 DernièreDernière
Affichage des résultats 1 à 15 sur 20

c++ : appeler une fonction d'une classe dérivée

  1. destroyedlolo

    Date d'inscription
    mai 2008
    Localisation
    Nonglard (a cote d'Annecy)
    Messages
    202

    Unhappy c++ : appeler une fonction d'une classe dérivée

    Bonjour,

    J'ai une classe définie comme suit :

    Code:
    class Context : virtual public Network, virtual public Porte, virtual public MQTTcon {
     ...
    public:
    	void save( void ){
    		this->crc = this->crc32();
    		ESP.rtcUserMemoryWrite(0, (uint32_t*)this, sizeof(*this));
    	}
    ...
    };
    Dans les classes dont elles dérivent, j'ai le besoin d'appeler le save() de Context.

    J'ai donc fait
    Code:
    class Network {
    ...
    protected:
    	virtual void save( void ) = 0;
    ...
    	enum NetworkMode connect( void ){
    ... bla bla bla ...
    		this->status();
    		this->save();
    	}
    };
    Et là, c'est le drame : "Load or store to an unaligned address"
    Si je commente le this->save(); plus de crash ...
    Je m'y prend donc mal : quelle serait la solution ?

    Merci

    -----

     


    • Publicité



  2. Jack

    Date d'inscription
    avril 2003
    Localisation
    Metz
    Messages
    16 219

    Re : c++ : appeler une fonction d'une classe dérivée

    Dans la classe Network, la fonction save est virtuelle pure, donc Network est une classe abstraite.
    Du coup, this->save(); n'a pas de sens puisque save n'est pas définie. Et this non plus n'a pas de sens puisque la classe n'est pas instanciable.

    A+
     

  3. destroyedlolo

    Date d'inscription
    mai 2008
    Localisation
    Nonglard (a cote d'Annecy)
    Messages
    202

    Re : c++ : appeler une fonction d'une classe dérivée

    Citation Envoyé par Jack Voir le message
    Dans la classe Network, la fonction save est virtuelle pure, donc Network est une classe abstraite.
    Du coup, this->save(); n'a pas de sens puisque save n'est pas définie.
    Ben du coup, comment puis-je appelé le save() de la classe qui hérite de Network ?
    En fait, toutes ces classes définissent des variables qui sont ensuite sauvées dans la mémoire RTC du bignou : mais comme toutes ces classes peuvent modifier leurs propres variable (a quel réseau somme nous connecté, situation de la porte, ...) j'ai donc besoin de pouvoir faire cette sauvegarde a plusieurs endroits.

    Citation Envoyé par Jack Voir le message
    Et this non plus n'a pas de sens puisque la classe n'est pas instanciable.
    Hum, dans ce cas, pourquoi Gcc ne fait pas d'erreur ? (j'ai mis -wall)
    Mon attention, c'est que le this corresponde à la classe Context, donc une fois l'héritage accomplis.
     

  4. pm42

    Date d'inscription
    juillet 2015
    Messages
    4 155

    Re : c++ : appeler une fonction d'une classe dérivée

    A vérifier mais je pense que ton code est correct du point de vue C++ mais que ton crash vient de la ligne :

    Code:
    ESP.rtcUserMemoryWrite(0, (uint32_t*)this, sizeof(*this));
    auquel tu passes des arguments qui ne respectent pas les contraintes d'alignement ou un truc dans le genre.
    Voir par ex https://github.com/esp8266/Arduino/issues/3365
     

  5. destroyedlolo

    Date d'inscription
    mai 2008
    Localisation
    Nonglard (a cote d'Annecy)
    Messages
    202

    Re : c++ : appeler une fonction d'une classe dérivée

    Ben j'étais tombé sur ce ticket lors de mes recherches avant de faire la demande ici ... mais ca plante aussi si ma fonction save() est vide
    Je pense donc que Jack a raison et que je ne peux peut-être pas construire mes objets comme ça.
    Je le fais en Lua où les objets sont vraiment créé dynamiquement, mais, à la réflexion, le C++ étant compilé, j'imagine qu'il doit savoir au moment de la compilation à quoi l'objet doit ressembler.

    Mais bon, je suis peut-être dans le faux donc si quelqu'un a une meilleur idée ...
     


    • Publicité



  6. pm42

    Date d'inscription
    juillet 2015
    Messages
    4 155

    Re : c++ : appeler une fonction d'une classe dérivée

    Tu essaies le code suivant qui est dérivé du tien :

    Code:
    #include <iostream>
    
    class Network {
    public:
        virtual void save( void ) = 0;
        void connect( void ){
            this->save();
        }
    };
    
    class Context : virtual public Network {
    public:
        void save( void ){
            std::cout << "in Context:save" << std::endl;
        }
    };
    
    int main(int argc, char** argv) {
            Context c;
            c.connect();
    }
    Et on crée bien la classe Context dans le main, on appelle connect défini dans Network dessus qui elle même appelle save.
    Et naturellement, on appelle le save de Context.

    Si on n'avait pas ce genre de comportement, les méthodes virtuelles et classes abstraites ne serviraient pas à grand chose.
    Donc ton problème est ailleurs à mon avis.
     

  7. Jack

    Date d'inscription
    avril 2003
    Localisation
    Metz
    Messages
    16 219

    Re : c++ : appeler une fonction d'une classe dérivée

    Citation Envoyé par pm42 Voir le message
    Donc ton problème est ailleurs à mon avis.
    Tu as sûrement raison.

    L'erreur semble donc indiquer une erreur d'alignement mémoire dû à une taille de bloc non adaptée lors de l'écriture. Ca a l'air très spécifique à l'implantation mémoire du système sur lequel tu travailles, un arduino à priori. C'est un problème récurrent semble-t-il: https://github.com/esp8266/Arduino/issues/2875
     

  8. destroyedlolo

    Date d'inscription
    mai 2008
    Localisation
    Nonglard (a cote d'Annecy)
    Messages
    202

    Re : c++ : appeler une fonction d'une classe dérivée

    Le code complet se trouve sur mon github si vous voulez voir (c'est loin d'etre fini) et c'est en effet pour un ESP8266 qui peut se programmer comme un Arduino.
    Pour économiser la batterie , je le met en mode DeepSleep au bout duquel il reboote et perd donc tous les contenu de sa mémoire ... sauf une petite zone nommée RTC. Le but de mon binse est d'y conserver certaines infos du contexte (sur quel réseau nous sommes connecté, position de la porte, consigne venant de la domotique, ...).
    Pour se faire, j'ai défini plusieurs classes en fonction du "domaine" (réseau, porte, ...) dont le contexte hérite : tous les champs seront sauvegardés dans la RTC. J'ai fait des tests simple et ca fonctionne : je n'ai bien que les champs dans le RTC, mais il n'y a que depuis que j'ai des save() dans les classes parentes que ca ne fonctionnent plus.

    Vu que pm42 nous dit, code à l’appui, que ce genre d'appel devrait fonctionner, je suis vraiment démuni. Je ne suis pas sur non plus que ca vienne de l'alignement des données elles-même vu que ca plante aussi avec un save() vide, peut etre plus un pb de pointeur sur les fonctions
    Après, l'ESP fonctionne suivant l'architecture Harvard donc le compilo fait peut-être un méli mélo a ce niveau ... mais pourquoi ?
    Je ferai le tests avec le code simple de pm42 ce soir pour voir si le pb vient de la.
    Dernière modification par destroyedlolo ; 19/12/2017 à 12h36.
     

  9. destroyedlolo

    Date d'inscription
    mai 2008
    Localisation
    Nonglard (a cote d'Annecy)
    Messages
    202

    Re : c++ : appeler une fonction d'une classe dérivée

    Bonsoir,

    Voila ce que j'ai essayé sur l'ESP :

    Code:
    void setup() {
      // put your setup code here, to run once:
    	Serial.begin(115200);
    	delay(100);
    }
    
    class Network {
    public:
        virtual void save( void ) = 0;
        void connect( void ){
    			Serial.println("N1");
          this->save();
        }
    };
    
    class Network2 {
    public:
        virtual void save( void ) = 0;
        void connect2( void ){
    			Serial.println("N2");
          this->save();
        }
    };
    
    class Context : public Network, public Network2 {
    public:
        void save( void ){
        	Serial.println("Save");
        }
    };
    
    void loop() {
    	Context c;
    	c.connect();
    	c.connect2();
    
    	ESP.deepSleep( 20e3 );
    }
    Évidemment, ca ne plante pas ... Je vais donc rajouter petit bout par petit bout mon code jusqu'a ce que ca crash ...
     

  10. Merlin95

    Date d'inscription
    octobre 2015
    Messages
    650

    Re : c++ : appeler une fonction d'une classe dérivée

    La seule ligne différente est :

    Code:
    class Context : virtual public Network {
    vs

    Code:
    class Context : public Network {
     

  11. destroyedlolo

    Date d'inscription
    mai 2008
    Localisation
    Nonglard (a cote d'Annecy)
    Messages
    202

    Re : c++ : appeler une fonction d'une classe dérivée

    Oui, c'est parce que ca plante dans les 2 cas. Mes essais actuels sont sans le virtual.
     

  12. ID123

    Date d'inscription
    novembre 2017
    Messages
    103

    Re : c++ : appeler une fonction d'une classe dérivée

    Tu n'as pas donné, dans ton code d'origine (-message #1), les lignes de code de création de l'objet. On est d'accord, c'est bien un objet Context que tu crées ?
    Autre piste : vu le message d'erreur, utiliser dans gcc une option "forte" d'alignement des données. par exemple sur deux mots.
     

  13. Jack

    Date d'inscription
    avril 2003
    Localisation
    Metz
    Messages
    16 219

    Re : c++ : appeler une fonction d'une classe dérivée

    Citation Envoyé par destroyedlolo Voir le message
    Oui, c'est parce que ca plante dans les 2 cas. Mes essais actuels sont sans le virtual.
    Vu l'héritage multiple, il faudra sûrement remettre virtual une fois le problème résolu.
     

  14. destroyedlolo

    Date d'inscription
    mai 2008
    Localisation
    Nonglard (a cote d'Annecy)
    Messages
    202

    [Trouvé] c++ : appeler une fonction d'une classe dérivée

    Bon, j'ai trouvé !!!

    Dans mes sous-classes, j'ai mis les variables que je veux sauvegarder.
    Donc en simplifiant, ca donnerait un truc du genre

    Code:
    class Network {
    	int réseau;
    
    protected:
    	virtual void save( void ) = 0;
    ...
    	enum NetworkMode connect( void ){
    ... bla bla bla ...
    		this->status();
    		this->save();
    	}
    };
    Ensuite, j'ai compiler un truc sur mon PC pour m'assurer que "this" pointe bien sur mes données et que sizeof(*this) à bien la taille de mes données.
    Sauf que, sauf que ... ben ça a marcher sur le PC, mais sur l'ESP
    Code:
    ESP.rtcUserMemoryRead(0, (uint32_t*)this, sizeof(*this))
    corrompe visiblement les pointeurs vers les méthodes et ... bbbbbboooommmm !

    Evidemment, c'était parfaitement capilotracté comme code, mais mes tests sur le PC ayant fonctionné, je me suis dit que ca serait plus élégant que de créer une structure dédiée aux données ce qui me pose le probleme de concaténer les données après dans la mémoire ...
    Mais je ne vais pas y couper

    Bref, faut que je redesigne mon truc
    Dernière modification par destroyedlolo ; 20/12/2017 à 18h07.
     

  15. destroyedlolo

    Date d'inscription
    mai 2008
    Localisation
    Nonglard (a cote d'Annecy)
    Messages
    202

    Re : [Trouvé] c++ : appeler une fonction d'une classe dérivée

    Bon ben voila, c'est corrigé.

    Bonnes fetes.
     


    • Publicité







Sur le même thème :


    301 Moved Permanently

    301 Moved Permanently


    nginx/1.2.1



 

Discussions similaires

  1. [Programmation] PIC16F : Comment appeler une fonction uniquement au reset externe?
    Par AmigaOS dans le forum Électronique
    Réponses: 15
    Dernier message: 03/08/2017, 12h22
  2. Appeler un tableau dans une fonction
    Par Galibble dans le forum Programmation et langages, Algorithmique
    Réponses: 17
    Dernier message: 28/02/2015, 15h53
  3. Pic C Appeler une fonction dans une interruption
    Par ashen59 dans le forum Électronique
    Réponses: 8
    Dernier message: 02/12/2012, 12h01
  4. Fonction de classe C infini à dérivée positive
    Par Leonhardo dans le forum Mathématiques du supérieur
    Réponses: 10
    Dernier message: 02/03/2010, 00h50
  5. comment appeler une fonction ecrite en C++ sur Matlab
    Par joel dans le forum Logiciel - Software - Open Source
    Réponses: 3
    Dernier message: 17/06/2005, 15h35