IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Héritage de classes.


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 57
    Par défaut Héritage de classes.
    Bonjour,

    Je suis toujours sur le projet pour lequel j'avais demandé de l'aide dans ce thread: http://www.developpez.net/forums/sho...d.php?t=154525

    Après avoir un peu avancé, je suis face à un nouveau problème.

    A la compilation j'obtiens cette erreur:

    c:\Documents and Settings\Fabrice\Bureau\Project\C++\GATest\GADiploid.h(30) : error C2504: 'GABinaryString' : classe de base non définie
    Celle-ci concerne le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    #ifndef _ga_binstr_h_
    #define _ga_binstr_h_
     
    #include <string.h>
    #include <ga/gatypes.h>
    #include <ga/garandom.h>
    #include <ga/GABinStr.h>
    #include <ga/GAGenome.h>
     
     
    #define GA_BINSTR_CHUNKSIZE 32	  // size of the chunks of bits we allocate
     
     
    class GADiploid : public GABinaryString, public GAGenome
    {
    	public:
    		GADiploid(unsigned int s);
    		GADiploid::GADiploid(const GADiploid& orig);
     
    		virtual ~GADiploid();
    		void copy(const GADiploid&);
     
    	int resize(unsigned int);		// pass desired size, in bits
    	int size() const {return sz;}
     
    	short bit(unsigned int a, unsigned int c) const
    	{
    		if (c = '1')
    			return(Chrom_1->bit(a));
    		else 
    			return(Chrom_2->bit(a));
    	}
     
    	short bit(unsigned int a, short val, unsigned int c)
    	{	// set/unset the bit
    		if (c = '1')
    			return(Chrom_1->bit(a, val));
    		else
    			return(Chrom_2->bit(a, val));
    	}
     
    	int equal(const GADiploid & b,
    		unsigned int r, unsigned int x, unsigned int l, unsigned int c) const
    	{
    		if (c = '1')
    			return(Chrom_1->equal(b.Chrom_1[0], r, x, l));
    		else
    			return(Chrom_2->equal(b.Chrom_2[0], r, x, l));
    	}
     
    	void copy(const GADiploid & orig,
    			unsigned int r, unsigned int x, unsigned int l, unsigned int c)
    	{
    		if (c = '1') Chrom_1->copy(orig.Chrom_1[0], r, x, l);
    		else		 Chrom_2->copy(orig.Chrom_2[0], r, x, l);
    	}
     
    	void move(unsigned int r, unsigned int x, unsigned int l, unsigned int c)
    	{
    		if (c = '1') Chrom_1->move(r, x, l);
    		else		 Chrom_2->move(r, x, l);
    	}
     
    	void set(unsigned int a, unsigned int l, unsigned int c)
    	{
    		if (c = '1') Chrom_1->set(a, l);
    		else		 Chrom_2->set(a, l);
    	}
     
    	void unset(unsigned int a, unsigned int l, unsigned int c)
    	{
    		if (c = '1') Chrom_1->unset(a, l);
    		else		 Chrom_2->unset(a, l);
    	}
     
    	void randomize(unsigned int a, unsigned int l, unsigned int c)
    	{
    		if (c = '1') Chrom_1->randomize(a, l);
    		else		 Chrom_2->randomize(a, l);
    	}
     
    	void randomize(unsigned int c)
    	{
    		if (c = '1') Chrom_1->randomize();
    		else		 Chrom_2->randomize();
    	}
     
    	GABinaryString *Chrom_1;
    	GABinaryString *Chrom_2;
    	//GABinaryString Mask;
     
    	protected:
    	unsigned int sz;		// size of chrom
    	unsigned int SZ;		// size of the memory allocated
    	unsigned int csz;		// size of chunks we allocate
     
    };
     
    #endif
    Je travaille sur une bibliothèque que je cherche à étendre. J'ai repris l'un des fichiers de cette bibliothèque et l'ai modifié pour obtenir le code qui précède.

    Pour résoudre l'erreur j'ai essayé de commenter le ifndef:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //#ifndef _ga_binstr_h_
    //#define _ga_binstr_h_
     
    [...]
     
    //#endif
    L'erreur disparaît, mais j'obtiens maintenant cette erreur:

    c:\Documents and Settings\Fabrice\Bureau\Project\C++\GATest\GADiploid.cpp(35) : error C2512: 'GABinaryString' : aucun constructeur par défaut approprié disponible
    Celle-ci concernant ce fichier:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ga/gaerror.h>
    #include <GADiploid.h>
     
     
     
    GADiploid::GADiploid(unsigned int s): GABinaryString(s)
    {
    	Chrom_1 = new GABinaryString(s);
    	Chrom_2 = new GABinaryString(s);
    	//resize(s);
     
    	//Mask = new GABinaryString(s);
    }
     
    GADiploid::GADiploid(const GADiploid& orig)
    {
    	sz=0; SZ=0; data=(GABit *)0;
    	copy(orig);
    }
     
    void
    GADiploid::copy(const GADiploid& orig)
    {
      if(&orig == this) return;
      Chrom_1->copy(orig.Chrom_1[0]);
      Chrom_2->copy(orig.Chrom_2[0]);
    }
     
    int
    GADiploid::resize(unsigned int x)
    {
      Chrom_1->resize(x);
      Chrom_2->resize(x);
     
      return(sz = x);
    }
    Le compilateur me réclame un constructeur par défaut alors que celui-ci semble bien défini dans le fichier suivant (fichier que j'ai récupéré dans la bibliothèque, sans modification):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    #ifndef _ga_binstr_h_
    #define _ga_binstr_h_
     
    #include <string.h>
    #include <ga/gatypes.h>
    #include <ga/garandom.h>
     
    #define GA_BINSTR_CHUNKSIZE 32	  // size of the chunks of bits we allocate
     
     
    class GABinaryString {
    public:
      GABinaryString(unsigned int s){
        csz=GA_BINSTR_CHUNKSIZE; sz=0; SZ=0; data=(GABit *)0;
        resize(s);
      }
      GABinaryString(const GABinaryString& orig){
        sz=0; SZ=0; data=(GABit *)0;
        copy(orig);
      }
      virtual ~GABinaryString(){delete [] data;}
      void copy(const GABinaryString&);
      int resize(unsigned int);		// pass desired size, in bits
      int size() const {return sz;}
     
      short bit(unsigned int a) const {
        return(data[a]);
      }
      short bit(unsigned int a, short val) {	// set/unset the bit
        return(data[a] = (val ? 1 : 0));
      }
      int equal(const GABinaryString & b,
    	    unsigned int r, unsigned int x, unsigned int l) const {
        return(memcmp(&(data[r]),&(b.data[x]),l*sizeof(GABit))?0:1);
      }
      void copy(const GABinaryString & orig,
    	    unsigned int r, unsigned int x, unsigned int l){
        memcpy(&(data[r]), &(orig.data[x]), l*sizeof(GABit));
      }
      void move(unsigned int r, unsigned int x, unsigned int l){
        memmove(&(data[r]), &(data[x]), l*sizeof(GABit));
      }
      void set(unsigned int a, unsigned int l){
        memset(&(data[a]), 1, l*sizeof(GABit));
      }
      void unset(unsigned int a, unsigned int l){
        memset(&(data[a]), 0, l*sizeof(GABit));
      }
      void randomize(unsigned int a, unsigned int l){
        for(unsigned int i=0; i<l; i++) 
          data[i+a] = (GABit)GARandomBit();
      }
      void randomize(){
        for(unsigned int i=0; i<sz; i++) 
          data[i] = (GABit)GARandomBit();
      }
     
    protected:
      unsigned int sz;		// size of chrom
      unsigned int SZ;		// size of the memory allocated
      unsigned int csz;		// size of chunks we allocate
      GABit *data;			// the data themselves
    };
     
    #endif
    Deux questions:

    -A quoi sert le code #ifndefine... #define... #endif que j'ai mis en commentaire?
    -Pour quoi le compilateur me réclame-t-il un constructeur par défaut?

    Merci d'avance pour vos réponses.

  2. #2
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Ben non, il n'y a pas de constructeur par défaut défini..
    Les "_ga_binstr_h_" servent à protéger une redéfinition, mais si tu utilises la même macro - _ga_binstr_h_ - pour 2 fichiers d'en-têtes, le deuxième sera comme inexistant.
    Il te demande un constructeur par défaut parce que dans un des constructeur de la classe fille, il est appelé.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 57
    Par défaut
    Citation Envoyé par Miles
    Ben non, il n'y a pas de constructeur par défaut défini..
    Les "_ga_binstr_h_" servent à protéger une redéfinition, mais si tu utilises la même macro - _ga_binstr_h_ - pour 2 fichiers d'en-têtes, le deuxième sera comme inexistant.
    Il te demande un constructeur par défaut parce que dans un des constructeur de la classe fille, il est appelé.
    Pour la 1ère question j'ai trouvé, c'est juste que j'ai recopié bêtement le fichier d'origine sans modifier le nom dans le #define, donc ça faisait automatiquement une double définition.

    Pour la 2ème question, j'ai repris le modèle d'un fichier de la bibliothèque (qui compile parfaitement quand je ne rajoute pas mes fichiers maisons).

    Mon fichier, GADiploid, s'inspire du fichier GA1DBinStrGenome qui hérite du fichier GABinStrGenome.

    Voilà le code du fichier d'origine.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    #include <ga/gaerror.h>
    #include <ga/garandom.h>
    #include <ga/GA1DBinStrGenome.h>
    #include <ga/GAMask.h>
     
    #define SWAP(a,b) {unsigned int tmp=a; a=b; b=tmp;}
     
    /* ----------------------------------------------------------------------------
       Genome class definition
    ---------------------------------------------------------------------------- */
    // Set all the initial values to NULL or zero, then allocate the space we'll
    // need (using the resize method).  We do NOT call the initialize method at
    // this point - initialization must be done explicitly by the user of the
    // genome (eg when the population is created or reset).  If we called the
    // initializer routine here then we could end up with multiple initializations
    // and/or calls to dummy initializers (for example when the genome is 
    // created with a dummy initializer and the initializer is assigned later on).
    GA1DBinaryStringGenome::
    GA1DBinaryStringGenome(unsigned int len, 
    		       GAGenome::Evaluator f, void * u) :
    GABinaryString(len),
    GAGenome(DEFAULT_1DBINSTR_INITIALIZER, 
    	 DEFAULT_1DBINSTR_MUTATOR,
    	 DEFAULT_1DBINSTR_COMPARATOR) {
      evaluator(f);
      userData(u);
      crossover(DEFAULT_1DBINSTR_CROSSOVER); // assign the default sexual crossover
      nx=minX=maxX=0;
      resize(len);
    }
     
     
    // This is the copy initializer.  We set everything to the default values, then
    // copy the original.  The BinaryStringGenome creator takes care of zeroing
    // the data and sz members.
    GA1DBinaryStringGenome::
    GA1DBinaryStringGenome(const GA1DBinaryStringGenome& orig) :
    GABinaryString(orig.GABinaryString::size()),
    GAGenome() {
      nx=minX=maxX=0;
      GA1DBinaryStringGenome::copy(orig);
    }
     
    GA1DBinaryStringGenome::~GA1DBinaryStringGenome() {
    }
    Le code des deux autres fichiers est donné dans le post précédent.
    Voilà la partie incriminée par le compilateur (j'ai noté l'emplacement de l'erreur):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    GADiploid::GADiploid(unsigned int s): GABinaryString(s)
    {
    	Chrom_1 = new GABinaryString(s);
    	Chrom_2 = new GABinaryString(s);
    	//resize(s);
     
    	//Mask = new GABinaryString(s);
    }
     
    GADiploid::GADiploid(const GADiploid& orig)
    {/*** Erreur ici ***/
    	sz=0; SZ=0; data=(GABit *)0;
    	copy(orig);
    }
    Comme je disais, il ne devrait pas y avoir de problème de classe par défaut, puisqu'il fonctionne avec l'autre fichier. Et j'aimerais éviter de modifier GABinStr et GA1DBinStrGenome, puisqu'ils font partie de la bibliothèque d'origine.

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Regarde mieux.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 57
    Par défaut
    Citation Envoyé par Miles
    Regarde mieux.
    Euh je veux bien, mais ça fait... 5 jours que je regarde.

    Une petite piste (fichier? fonction?), please?

  6. #6
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Je t'ai dit de regarder les constructeurs.

    Ton constructeur par recopie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    GADiploid::GADiploid(const GADiploid& orig)
    {/*** Erreur ici ***/
    	sz=0; SZ=0; data=(GABit *)0;
    	copy(orig);
    }
    L'exemple que tu as mal repris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    GA1DBinaryStringGenome::
    GA1DBinaryStringGenome(const GA1DBinaryStringGenome& orig) :
    GABinaryString(orig.GABinaryString::size()),
    GAGenome() {
      nx=minX=maxX=0;
      GA1DBinaryStringGenome::copy(orig);
    }
    Le pire est que ton erreur est exactement là où tu l'as indiqué, et c'est exactement là où tu n'as pas mis la liste d'initialisation.

  7. #7
    Membre Expert
    Avatar de hiko-seijuro
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 011
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 011
    Par défaut
    le code que tu as mis en commentaire permet d'assurer l'unicité du parcours du fichier. voir ici

    pour ta deuxièyme question poste seulement la ligne concernée car il faut chercher et ça prend du temps

  8. #8
    Membre émérite Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Par défaut
    Bonjour,

    Le bloc ifndef...define...endif sert à protéger le header contre l'inclusion multiple.

    Soit un entête A.h, sans cette clause et sans .c.

    Immaginons deux modules B.cpp et D.cpp qui inclus chacun A.h. B est compilé avant D.

    Au moment où B est compilé, le compilateur défini les symboles de l'entête A.h.

    Ensuite, D est compilé. Le compilateur veut aussi définir les symboles de A.h. Problème: ceux-ci existent déjà. La compilation échoue.

    Si les clause ifndef/def/endif sont présentes, lors de la compilation de D, le symbole A_H est défini, donc le compilayeur cherche un #else, comme il n'y en a pas, il saute au #endif. Les symboles ne sont pas redéfinis. La compilation continue.

    Pour la deuxième question, règle d'abord le premier problème de classe de base non définie.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Héritage et classes
    Par steinfield dans le forum Langage
    Réponses: 5
    Dernier message: 23/10/2006, 23h44
  2. conflit d'inclusions et Héritage de classe
    Par gedeon555 dans le forum C++
    Réponses: 7
    Dernier message: 01/10/2006, 19h48
  3. [POO] Problème héritage des classes PHP4
    Par zana74 dans le forum Langage
    Réponses: 2
    Dernier message: 15/08/2006, 16h00
  4. [POO] Héritage vs classe dans une classe
    Par robichou dans le forum Langage
    Réponses: 4
    Dernier message: 06/08/2006, 23h51
  5. [OO] Héritage - Mixins Classes
    Par djmalo dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 01/03/2005, 23h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo