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

  1. #1
    Membre du Club
    [Polymorphisme] Relecture de code pour un système de recettes de cuisine
    Bonjour, je suis nouveau sur developpez.net .
    J'ai bien lu les règles, et j'ose espérer que ma demande ne sort pas des clous.

    J'ai un travail à terminer dans le cadre d'un cours en ligne sur le C++.
    Cela fait des semaines que je m'arrache les cheveux, et je n'ai qu'un correcteur automatique pour avoir des retours sur la "qualité" de mon programme.

    Le code n'est pourtant pas compliqué, mais je ne suis pas assez bon en debug et je me sens seul.

    Le problème concerne l'appel de méthodes sur une liste d'objets.
    Et sur chacun de ces objets, on peut appliquer le polymorphisme.. Mais le programme ne s’exécute pas comme prévu. Quelque chose cloche avec le dynamic dispatch.

    L'exercice est l' "Exercice 1 " du fichier pdf.
    Je n'ai pas moyen de publier ici le retour du correcteur automatique pour l'instant, ce sera fait dans la soirée. Ce sera plus facile pour vous de m'aider à ce moment.
    Merci pour votre patience.


    Le code fait 200 lignes environ. Une grande partie est correcte, mais certaines méthodes sont incorrectes.

    Merci beaucoup pour votre aide.

    Cordialement,

  2. #2
    Membre régulier
    Bonjour,

    Pourrais-tu nous glisser ce que tu as déjà réalisé en code afin que l'on puisse t'aider ?

    Egalement, qu'est ce que tu ne comprends pas ? Un concept, une fonction ?

  3. #3
    Membre du Club
    Bonsoir..

    Le code est tellement long, je l'avais mis en pièce jointe du 1er message, et je vais essayer de le publier ici.
    J'ai tout codé, mais certaines fonctions sont problématiques.
    Je ne suis pas sur d'avoir réussi à faire en sorte que Produit::adapter, Produit::quantiteTotale soient bien polymorphiques.
    Je ne sais pas non plus si les quantités calculées dans Recette::adapter sont correctes.


    Si je prends le main dans l'ordre séquentiel :
    Le 1er problème est que
    Lignes 21 à 28, mon programme a écrit :
    " Recette "glaçage au chocolat parfumé" x 1:"
    " 1. 2.000000 gouttes de extrait d'amandes"
    " 2. 1.000000 portion(s) de glaçage au chocolat"
    " Recette "glaçage au chocolat" x 1:"
    " 1. 200.000000 grammes de chocolat noir"
    " 2. 25.000000 grammes de beurre"
    " 3. 100.000000 grammes de sucre glace"
    "Cette recette contient 100 grammes de beurre"

    là où il aurait du afficher ceci :

    " Recette "glaçage au chocolat parfumé" x 2: "
    " 1. 4.000000 gouttes de extrait d'amandes"
    " 2. 2.000000 portion(s) de glaçage au chocolat"
    " Recette "glaçage au chocolat" x 2: "
    " 1. 400.000000 grammes de chocolat noir"
    " 2. 50.000000 grammes de beurre"
    " 3. 200.000000 grammes de sucre glace"
    "Cette recette contient 150 grammes de beurre"

    J'ai l'impression qu'une partie de ma recette n'a pas été affichée correctement.. Qu'en pensez-vous ?

    Je peux bien sûr fournir d'autres infos, si demandé.

    Pour les diverses classes :
    classe "Produit"
    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
     
     
    class Produit
    {
     
    protected:
      string nom_;
      string unite_;
     
    public:
      Produit(string a, string b = "") : nom_(a), unite_(b) {}
     
      string getNom() const
      {
        return nom_;
      }
      string getUnite() const
      {
        return unite_;
      }
      virtual string toString() const
      {
        return nom_;
      }
     
      const Produit *adapter(double d) const
      {
        return this;
      }
     
      virtual double quantiteTotale(const string &nomProduit) const //produit
      {
        if (getNom() == nomProduit)
        {
          return 1;
        }
        else
        {
          return 0;
        }
      }
    };


    Classe Produit Cuisiné, qui hérite de Produit et qui contient une recette
    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
    class ProduitCuisine : public Produit
    {
    public:
      ProduitCuisine(string no) : Produit(no, "portion(s)"), recetteCuisine(no) {}
     
      void ajouterARecette(const Produit &prod, double quan)
      {
        recetteCuisine.ajouter(prod, quan);
      }
     
      //const ProduitCuisine *adapter(double n)  override
      const Produit *adapter(double n) const
      {
     
        ProduitCuisine *pp = new ProduitCuisine(getNom());
        pp->recetteCuisine.adapter(n); //adapter(n);
        return pp;
      }
     
      string toString() const override
      {
        string s;
        s += Produit::toString();
        s += "\n";
        s += recetteCuisine.toString();
        //s += ":";
        return s;
      }
     
      double quantiteTotale(const string &nomProduit) //produit Cuisine
      {
        if (getNom() == nomProduit)
        {
          return 1;
        }
        else
        {
          return recetteCuisine.quantiteTotale(nomProduit);
        }
      }
     
    private:
      Recette recetteCuisine;
    };

    Classe ingrédient :
    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
     
     
    class Ingredient
    {
    private:
      const Produit &produit_;
      double quantite;
     
    public:
      Ingredient(const Produit &p, double q) : produit_(p), quantite(q) {}
     
      const Produit &getProduit() const //was virtual
      {
        return produit_;
      }
     
      double getQuantite() const
      {
        return quantite;
      }
     
      string descriptionAdaptee() const
      {
        ostringstream ss;
        ss << quantite; //Utiliser ss comme cout
     
        string s = std::to_string(quantite) + " " + produit_.getUnite() + " de ";
     
        const Produit *produitadap = produit_.adapter(quantite);
     
        s = s + produitadap->toString();
        return s;
      }
     
      double quantiteTotale(const string &nomProduit) const
      {
        return (getQuantite() * getProduit().quantiteTotale(nomProduit));
      }
    };

    Classe recette + fonction d'affichage:
    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
     
    class Recette
    {
    private:
      vector<Ingredient> liste;
      string nom_recette_;
      double nbFois_;
     
    public:
      Recette(string nom, double q = 1) : nom_recette_(nom), nbFois_(q) {}
     
      double getnbFois_() const
      {
        return nbFois_;
      }
      string getnom_recette_() const
      {
        return nom_recette_;
      }
      void ajouter(const Produit &p, double quantite)
      {
        Ingredient i(p, quantite * nbFois_);
        liste.push_back(i);
      }
     
      Recette adapter(double n)
      {
        Recette r(nom_recette_, n * nbFois_);
        for (size_t i(0); i < liste.size(); i++)
        {
          r.ajouter(liste[i].getProduit(), liste[i].getQuantite() * n / nbFois_); //enlever le n ? 
        }
     
        return r;
      }
     
      string toString() const // was virtual
      {
        string s;
     
        ostringstream ss;
        ss << nbFois_; //Utiliser ss comme cout
        string nbFois_str = ss.str();
     
        s = s + "  Recette \"" + nom_recette_ + "\" x " + nbFois_str + ":" + "\n";
     
        for (size_t i(0); i < liste.size(); i++)
        {
          s = s + "  " + std::to_string(i + 1) + ". " + liste[i].descriptionAdaptee(); // DOUTE ICI
          if (i != (liste.size() - 1))
          {
            s = s + "\n";
          }
        }
     
        return s;
      }
     
      double quantiteTotale(const string &nomProduit) const  //recette
      {
        double somme(0);
     
        for (size_t i(0); i < liste.size(); i++)
        {
          if (liste[i].getProduit().getNom() == nomProduit)
          {
            somme = somme + liste[i].getQuantite();
          }
        }
        return somme;
      }
    };
     
     
    void afficherQuantiteTotale(const Recette& recette, const Produit& produit)
    {
      string nom = produit.getNom();
      cout << "Cette recette contient " << recette.quantiteTotale(nom)
           << " " << produit.getUnite() << " de " << nom << endl;
    }

    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
     
     
    int main()
    {
      // quelques produits de base
      Produit oeufs("oeufs");
      Produit farine("farine", "grammes");
      Produit beurre("beurre", "grammes");
      Produit sucreGlace("sucre glace", "grammes");
      Produit chocolatNoir("chocolat noir", "grammes");
      Produit amandesMoulues("amandes moulues", "grammes");
      Produit extraitAmandes("extrait d'amandes", "gouttes");
     
      ProduitCuisine glacage("glaçage au chocolat");
      // recette pour une portion de glaçage:
      glacage.ajouterARecette(chocolatNoir, 200);
      glacage.ajouterARecette(beurre, 25);
      glacage.ajouterARecette(sucreGlace, 100);
      cout << glacage.toString() << endl;
     
      ProduitCuisine glacageParfume("glaçage au chocolat parfumé");
      // besoin de 1 portions de glaçage au chocolat et de 2 gouttes
      // d'extrait d'amandes pour 1 portion de glaçage parfumé
     
      glacageParfume.ajouterARecette(extraitAmandes, 2);
      glacageParfume.ajouterARecette(glacage, 1);
      cout << glacageParfume.toString() << endl;
     
      Recette recette("tourte glacée au chocolat");
      recette.ajouter(oeufs, 5);
      recette.ajouter(farine, 150);
      recette.ajouter(beurre, 100);
      recette.ajouter(amandesMoulues, 50);
      recette.ajouter(glacageParfume, 2);
     
      cout << "===  Recette finale  =====" << endl;
      cout << recette.toString() << endl;
      afficherQuantiteTotale(recette, beurre);
      cout << endl;
     
      // double recette
      Recette doubleRecette = recette.adapter(2);
      cout << "===  Recette finale x 2 ===" << endl;
      cout << doubleRecette.toString() << endl;
     
      afficherQuantiteTotale(doubleRecette, beurre);
      afficherQuantiteTotale(doubleRecette, oeufs);
      afficherQuantiteTotale(doubleRecette, extraitAmandes);
      afficherQuantiteTotale(doubleRecette, glacage);
      cout << endl;
     
      cout << "===========================\n" << endl;
      cout << "Vérification que le glaçage n'a pas été modifié :\n";
      cout << glacage.toString() << endl;
     
      return 0;
    }

  4. #4
    Membre du Club
    Est-ce que je n'ai pas fait une erreur de conception en écrivant dans Recette :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
     vector<Ingredient> liste;

    Au lieu par exemple de
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
      vector<Ingredient*> liste;
    ?

  5. #5
    Membre chevronné
    Salut
    ton code corrigé
    2 petites erreurs un <;> mal placé
    les classes ancêtres doivent impérativement être placées au début du code sinon il fait déclarer ces classes en Forward
    dans la classe Produit remplacement de protected en private
    ton code
    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
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
     
     
    #include <iostream>
    #include <vector>
    #include <sstream>
     
    using namespace std;
     
    //-----------------------------------------------------------------------------------------------------
    class Produit
    {
    private:
      string nom_;
      string unite_;
     
    public:
      Produit(string a, string b = "") : nom_(a), unite_(b) {}
     
      string getNom() const
      {
    	return nom_;
      }
      string getUnite() const
      {
    	return unite_;
      }
      virtual string toString() const
      {
    	return nom_;
      }
     
      const Produit *adapter(double d) const
      {
    	return this;
      }
     
      virtual double quantiteTotale(const string &nomProduit) const //produit
      {
    	if (getNom() == nomProduit)
    	{
    	  return 1;
    	}
    	else
    	{
    	  return 0;
    	}
      }
    };
     
    //-----------------------------------------------------------------------------------------------------
     
    class Ingredient
    {
    private:
      const Produit &produit_;
      double quantite;
     
    public:
      Ingredient(const Produit &p, double q) : produit_(p), quantite(q) {}
     
      const Produit &getProduit() const //was virtual
      {
    	return produit_;
      }
     
      double getQuantite() const
      {
    	return quantite;
      }
     
      string descriptionAdaptee() const
      {
    	ostringstream ss;
    	ss << quantite; //Utiliser ss comme cout
     
    	string s = std::to_string(quantite) + " " + produit_.getUnite() + " de ";
     
    	const Produit *produitadap = produit_.adapter(quantite);
     
    	s = s + produitadap->toString();
    	return s;
      }
     
      double quantiteTotale(const string &nomProduit) const
      {
    	return (getQuantite() * getProduit().quantiteTotale(nomProduit));
      }
    };
    //-----------------------------------------------------------------------------------------------------
     
     
     class Recette
    {
    private:
      vector<Ingredient> liste;
      string nom_recette_;
      double nbFois_;
     
    public:
      Recette(string nom, double q = 1) : nom_recette_(nom), nbFois_(q) {}
     
      double getnbFois_() const
      {
        return nbFois_;
      }
      string getnom_recette_() const
      {
    	return nom_recette_;
      }
      void ajouter(const Produit &p, double quantite)
      {
        Ingredient i(p, quantite * nbFois_);
        liste.push_back(i);
      }
     
      Recette adapter(double n)
      {
        Recette r(nom_recette_, n * nbFois_);
        for (size_t i(0); i < liste.size(); i++)
        {
          r.ajouter(liste[i].getProduit(), liste[i].getQuantite() * n / nbFois_); //enlever le n ?
        }
     
        return r;
      }
     
      string toString() const // was virtual
      {
    	string s;
     
        ostringstream ss;
    	ss << nbFois_; //Utiliser ss comme cout
        string nbFois_str = ss.str();
     
        s = s + "  Recette \"" + nom_recette_ + "\" x " + nbFois_str + ":" + "\n";
     
        for (size_t i(0); i < liste.size(); i++)
        {
    	  s = s + "  " + std::to_string(i + 1) + ". " + liste[i].descriptionAdaptee(); // DOUTE ICI
          if (i != (liste.size() - 1))
          {
    		s = s + "\n";
    	  }
        }
     
        return s;
      }
     
      double quantiteTotale(const string &nomProduit) const  //recette
      {
        double somme(0);
     
        for (size_t i(0); i < liste.size(); i++)
        {
          if (liste[i].getProduit().getNom() == nomProduit)
          {
            somme = somme + liste[i].getQuantite();
          }
        }
        return somme;
      }
    };
     
     
    void afficherQuantiteTotale(const Recette& recette, const Produit& produit)
    {
      string nom = produit.getNom();
      cout << "Cette recette contient " << recette.quantiteTotale(nom)
    	   << " " << produit.getUnite() << " de " << nom << endl;
    }
    //-----------------------------------------------------------------------------------------------------
     
     class ProduitCuisine : public Produit
    {
    public:
      ProduitCuisine(string no) : Produit(no, "portion(s)"), recetteCuisine(no) {}
     
      void ajouterARecette(const Produit &prod, double quan)
      {
    	recetteCuisine.ajouter(prod, quan);
      }
     
      //const ProduitCuisine *adapter(double n)  override
      const Produit *adapter(double n) const
      {
     
    	ProduitCuisine *pp = new ProduitCuisine(getNom());
    	pp->recetteCuisine.adapter(n); //adapter(n);
    	return pp;
      }
     
      string toString() const override
      {
    	string s;
    	s += Produit::toString();
    	s += "\n";
    	s += recetteCuisine.toString();
    	//s += ":";
    	return s;
      }
     
      double quantiteTotale(const string &nomProduit) //produit Cuisine
      {
    	if (getNom() == nomProduit)
    	{
    	  return 1;
    	}
    	else
    	{
    	  return recetteCuisine.quantiteTotale(nomProduit);
    	}
      }
     
    private:
      Recette recetteCuisine;
    };
    //-----------------------------------------------------------------------------------------------------
    t _main(int argc, _CHAR* argv[]) 
    {
         Produit oeufs("oeufs");
      Produit farine("farine", "grammes");
      Produit beurre("beurre", "grammes");
      Produit sucreGlace("sucre glace", "grammes");
      Produit chocolatNoir("chocolat noir", "grammes");
      Produit amandesMoulues("amandes moulues", "grammes");
      Produit extraitAmandes("extrait d'amandes", "gouttes");
     
      ProduitCuisine glacage("glaçage au chocolat");
      // recette pour une portion de glaçage:
      glacage.ajouterARecette(chocolatNoir, 200);
      glacage.ajouterARecette(beurre, 25);
      glacage.ajouterARecette(sucreGlace, 100);
      cout << glacage.toString() << endl;
     
      ProduitCuisine glacageParfume("glaçage au chocolat parfumé");
      // besoin de 1 portions de glaçage au chocolat et de 2 gouttes
      // d'extrait d'amandes pour 1 portion de glaçage parfumé
     
      glacageParfume.ajouterARecette(extraitAmandes, 2);
      glacageParfume.ajouterARecette(glacage, 1);
      cout << glacageParfume.toString() << endl;
     
      Recette recette("tourte glacée au chocolat");
      recette.ajouter(oeufs, 5);
      recette.ajouter(farine, 150);
      recette.ajouter(beurre, 100);
      recette.ajouter(amandesMoulues, 50);
      recette.ajouter(glacageParfume, 2);
     
      cout << "===  Recette finale  =====" << endl;
      cout << recette.toString() << endl;
      afficherQuantiteTotale(recette, beurre);
      cout << endl;
     
      // double recette
      Recette doubleRecette = recette.adapter(2);
      cout << "===  Recette finale x 2 ===" << endl;
      cout << doubleRecette.toString() << endl;
     
      afficherQuantiteTotale(doubleRecette, beurre);
      afficherQuantiteTotale(doubleRecette, oeufs);
      afficherQuantiteTotale(doubleRecette, extraitAmandes);
      afficherQuantiteTotale(doubleRecette, glacage);
      cout << endl;
     
      cout << "===========================\n" << endl;
      cout << "Vérification que le glaçage n'a pas été modifié :\n";
      cout << glacage.toString() << endl;
     
      return 0;
     
    }



    Cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  6. #6
    Membre du Club
    Merci pour cette correction.

    J'ai enfin trouvé ce qu'il fallait changer, mais j'ai un problème de const-correctness.

    Dans ProduitCuisine::adapter(),il faut copier l'adaptation de la recette du produit courant dans la recette du nouveau produit.

    Il faut passer de
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      const Produit *adapter(double n) const
      {
     
        ProduitCuisine *pp = new ProduitCuisine(getNom());
        pp->recetteCuisine.adapter(n); //adapter(n);
        // copier l'adaptation de la recette du produit courant dans la recette du nouveau produit
     
        return pp;
      }


    à


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      const Produit *adapter(double n) const
      {
     
    		ProduitCuisine *pp = new ProduitCuisine(getNom());
    		pp->recetteCuisine = recetteCuisine.adapter(n); //commentaire de l'ide
    		return this;
      }



    Mais l'IDE me précise :
    "l'objet a des qualificateurs de type incompatibles avec le membre fonction "Recette::adapter" -- le type d'objet est : const Recette"


    Ai-je oublié un const quelque part ?
    Réponse : oui, il fallait mettre " Recette adapter(double n) const " comme prototype.
    Merci

    Ps: J'ai fini par trouver le problème tout seul et mon programme tourne bien comme je le voulais, merci pour vos aides.

    Comment je peux faire pour avoir + d'aide à l'avenir ?
    Est-ce que je dois améliorer mon post ?
    Est-ce que ce genre de programme ne donne pas envie d'aider ?

    Si je tombe sur le même type de difficulté sur un programme plus volumineux et que je bloque tout seul, comment faire ?

  7. #7
    Membre chevronné
    Salut
    le temps de réponse à ta demande à été relativement court
    si a l'avenir tu veux obtenir plus rapidement encore des réponses je te conseille plutôt de poster dans des sous-forums de c++ https://www.developpez.net/forums/f65/c-cpp/outils-c-cpp/
    concernant ton code je te conseille de travailler plus génériquement, en oubliant pas par exemple les constructeurs de copies de tes différentes classes et , en séparant les déclarations de tes classes dans des fichiers <.h> et <.cpp>

    Au plaisir de t'aider à nouveau

    cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

###raw>template_hook.ano_emploi###