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 :

Interaction entre plusieurs classes


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Interaction entre plusieurs classes
    Bonjour a toutes et a tous ,
    Mon code fonctionne correctement , mais mon main est peut etre un peu trop surchargé . Je souhaiterai creer une 2 eme classe " Sauvegarde ".
    Je ne maitrise pas encore la notion de définition et d'instanciation lorsqu'il y a plus d'une classe : je ne sais pas comment les faire interagir entre elles .
    Voici le code tel qu'il est actuelement :

    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
    #ifndef COMPTE_H_
    #define COMPTE_H_
     
    class Compte
    {
     private :
    	int solde,rib;
     
     public :
    	Compte(int a);
    	int getsolde()const;
    	void setsolde(int b);
    	void saisir(int s);
    	void deposer(int montant);
            bool retirer(int montant);
            void afficher();
     
    };
    #endif


    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
    #include "compte.h"
    #include <iostream>
    #include <string>
    using namespace std;
     
    Compte :: Compte(int a):solde(0),rib(a){}
     
    int Compte::getsolde()const
    {
    	return solde;
    }
    void Compte :: setsolde(int b)
    {
    	solde = b;
    }
    void Compte :: deposer(int montant)
    {
    	solde += montant;
    }
    bool Compte ::retirer(int montant)
    {
        if(solde >= montant)
        {
        	solde -= montant;
        	cout <<"votre retrait a bien été éffectué sur votre compte" << endl;
        	return true;
        }else
        	cout <<"solde insuffisant , operation refusée" << endl;
        	return false;
    }
    void Compte :: afficher()
    {
        cout << "Le solde de votre compte : " << rib <<" est de : " << solde <<" euros" << endl;
    }
    void Compte :: saisir(int s)
    {
    	solde = s;
    }


    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
    int main()
    {
     Compte ccp (12348), livretA(987654);
     int a(0);
     fstream file("sauvegarde.txt",ios::in);
     
    	  if(file.is_open())
    	  {
    	       int input;
     
    	       file >> input;
    	       ccp.setsolde(input);
    	       file >> input;
    	       livretA.setsolde(input);
    	       file.close();
    	       cout << "solde lu avec succès" << endl; 
    	 }else{
    		cout << "solde non lu"<< endl;
    	  }
     
     do {
     cout << "Quelle operation souhaitez vous faire ?" << endl;
     
     cout << "1 : Afficher le solde de votre compte CCP: " << endl;
     cout << "2 : Afficher le solde de votre livret A : " << endl;
     cout << "3 : Saisir votre nouveau solde CCP : " << endl;
     cout << "4 : Saisir votre nouveau solde livret A : " << endl;
     cout << "5 : Faire un depot sur votre compte CCP : " << endl;
     cout << "6 : Faire un depot sur votre livret A : " << endl;
     cout << "7 : Faire un retrait sur votre compte CCP : " << endl;
     cout << "8 : Faire un retrait sur votre livret A : " << endl;
     cout << "9 : Faire un virement sur votre compte CCP : " << endl;
     cout << "10 : Faire un virement sur votre livret A : " << endl;
     cout << "11 : Quitter le programme " << endl;
     cin >> a;
     cin.ignore();
     switch(a)
     {
      case 1 :
    	  ccp.afficher();
    	  break;
      case 2 :
    	  livretA.afficher();
    	  break;
      case 3 :
         {
          int s(0);
          cout << "Entrez votre solde : " << endl;
          cin >> s;
          ccp.saisir(s);
         }
         break;
      case 4 :
         {
          int s(0);
          cout << "Entrez votre solde : " << endl;
          cin >> s;
          livretA.saisir(s);
         }
         break;
      case 5 :
         {
          int s(0);
          cout << " Quel est le montant de votre depot : " << endl;
          cin >> s ;
          ccp.deposer(s);
         }
         break;
      case 6 :
         {
          int s(0);
          cout << " Quel est le montant de votre depot : " << endl;
          cin >> s ;
          livretA.deposer(s);
         }
         break;
      case 7 :
         {
          int s(0);
          cout << " Quel est le montant de votre retrait : " << endl;
          cin >> s ;
          ccp.retirer(s);
         }
         break;
      case 8 :
         {
          int s(0);
          cout << " Quel est le montant de votre retrait : " << endl;
          cin >> s ;
          livretA.retirer(s);
         }
         break;
      case 11 :
        {
         fstream file("sauvegarde.txt",ios::out);
         if(file.is_open())
         {
    	 file << ccp.getsolde()<< endl;
              file << livretA.getsolde()<<endl;
    	  file.close();
              cout << "solde enregistré avec succès" << endl;
    	  }else{
    		  cout << "solde non enregistré"<< endl;
    	  }
    	  cout << "Aurevoir" << endl;
    	 }
    	  break;
      default :
    	  cout << "Mauvais choix " << endl;
    	  break;
     }
    }while( a != 11);
     
     return 0;
    }


    Je pensais faire quelque chose de ce genre mais ca ne fonctionne pas :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifndef SAUVEGARDE_H_
    #define SAUVEGARDE_H_
    #include<iostream>
     
    class Sauvegarde
    {
     public:
    	void sauvegarde();
    	void restitution();
     
    };
     
    #endif

    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
    #include "sauvegarde.h"
    #include "compte.h"
    using namespace std;
     
    void Sauvegarde::sauvegarde()
    {
    	fstream file("sauvegarde.txt",ios::out);
    		  if(file.is_open())
    		  {
    			  file << ccp.getsolde()<< endl;
    	                  file << livretA.getsolde()<<endl;
    			  file.close();
    			  cout << "solde enregistré avec succès" << endl;
    		  }else{
    			  cout << "solde non enregistré"<< endl;
    		  }
    		          cout << "Aurevoir" << endl;
    }
    void restitution()
    {
    	fstream file("sauvegarde.txt",ios::in);
     
    	 	  if(file.is_open())
    	 	  {
    	 	       int input;
     
    	 	       file >> input;
    	 	       ccp.setsolde(input);
    	 	       file >> input;
    	 	       livretA.setsolde(input);
    	 	       file.close();
    	 	       cout << "solde lu avec succès" << endl;
    	 	   }else{
    	 		  cout << "solde non lu"<< endl;
    	 	  }
    }


    Concretement , comment pourai je faire ?
    Merci de votre aide.

  2. #2
    Membre averti
    Les méthodes de ta classe Sauvegarde utilisent des variables inconnues : cpp et livretA. Il faudrait les ajouter, soit en paramètres, soit en données membres. Dans le premier cas, autant déclarer aussi ces méthodes static pour éviter d’avoir à instancier une classe dénuée du moindre état.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // Astuce : en 2020, tu peux raisonnablement remplacer tes gardes d’inclusion par un simple "#pragma once".
    #pragma once
     
    #include "compte.h"
     
    #include <iostream>
     
    class Sauvegarde
    {
    public:
    	static void sauvegarde(const Compte & ccp, const Compte & livretA);
    	static void restitution(Compte & ccp, Compte & livretA);
    };


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // ...
    case 11 :
    	Sauvegarde::sauvegarde(ccp, livretA);
    // ...


    En allant plus loin :

    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
    #pragma once
     
    #include "compte.h"
     
    #include <string>
    #include <vector>
     
    class SystemeDeFichiers
    {
    	static const std::string NOM_FICHIER_SAUVEGARDE;
     
    public:
    	void sauvegarder(const std::vector< const Compte * > & comptes) const;
     
    	void restaurer(const std::vector< Compte * > & comptes) const;
    };


    Ici aussi, les méthodes pourraient être static. Je les ai toutefois laissées en l’état au cas où une possible classe abstraite Persistance serait introduite dont SystemeDeFichiers ne serait qu’une implémentation parmi d’autres

  3. #3
    Nouveau membre du Club
    Je te remercie beaucoup de ta reponse !
    Je vais étudier tout ca de pres . Je n'ai pas encore vu ce point mais le " pragma once " est donc une alternative a ifndef ... je dois le mettre seulement au debut de mes fichiers header ?

  4. #4
    Expert éminent
    Citation Envoyé par chris7522 Voir le message
    le " pragma once " est donc une alternative a ifndef ... je dois le mettre seulement au debut de mes fichiers header ?
    Lis le wiki : pragma once

    C'est une manière non standard pour faire des include guard ... et d'après wiki c'est une solution qui semble ne pas fonctionner avec des fichiers ayant un même nom (mais dans un répertoire différent)

  5. #5
    Nouveau membre du Club
    Avez vous un cours , un livre a me conseiller , pour apprendre a faire interagir les classes dans les règles de l'art ?
    J'ai un mal de chien a trouver du contenu .

    D'avance merci .
    Passez un bon week-end et comme dit la dame de la météo , prenez soin de vous .

  6. #6
    Rédacteur/Modérateur

    Y'a pas de magie à l'oeuvre.
    Une classe ça interagit via ses fonctions et les paramètres que tu passes à ces fonctions.
    Si le paramètre vient d'une constante, entrée utilisateur ou d'une autre classe c'est juste comment tu construis ton programme.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Expert éminent
    Citation Envoyé par chris7522 Voir le message
    Avez vous un cours , un livre a me conseiller , pour apprendre a faire interagir les classes dans les règles de l'art ?
    Il n'y a pas de livres Parce que ce que tu demandes, cela s'acquière avec des bonnes pratiques et de l'expérience ( et c'est [très] souvent les délais et le cahier des charges qui sont l'arbitre)

    Les bonnes pratiques,
    • composition/ agrégation VS l'héritage (teaser : on utilise entre 10 et 15% l'héritage)
    • les patrons de conception ("design patterns") (<- lien wikibooks en français) (teaser : ce sont des patrons de solutions à adapter)
    • Toute la conception avec des couches : data layer, presentation layer, MVC/ MVP - Model-View-Presenter/ MVVC, business logic, ...

  8. #8
    Nouveau membre du Club
    On est bien daccord que c'est en forgeant qu'on devient forgeron , mais il y a forcement eu une phase theorique dans votre apprentissage , du moins lorsque vous debutiez . &#9786;

  9. #9
    Membre averti
    Alors, certes, la magie n’existe pas, mais pour un débutant tout parait un peu mystérieux et pas du tout évident. Internet regorge d’informations utiles, mais la qualité a un prix et si tu veux un contenu récent, électronique ou non, de qualité et pédagogique, un (bon) bouquin s’impose généralement. J’hésite toutefois à t’en conseiller un, mes références n’étant plus à jour depuis longtemps. Le classique de Bjarne Soustroup, le créateur du C++, à jour pour le C++11, est sans doute une valeur sûre, mais tu peux aussi jeter un oeil à la sélection de Developpez.com.


    @foetus : Peut-être que d’anciens compilateurs avaient ce défaut, mais, sauf cas assez exotiques, le pragma once fonctionne aussi avec des fichiers homonymes dans des dossiers distincts.

  10. #10
    Nouveau membre du Club
    Citation Envoyé par Chatanga Voir le message
    Les méthodes de ta classe Sauvegarde utilisent des variables inconnues : cpp et livretA. Il faudrait les ajouter, soit en paramètres, soit en données membres. Dans le premier cas, autant déclarer aussi ces méthodes static pour éviter d’avoir à instancier une classe dénuée du moindre état.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // Astuce : en 2020, tu peux raisonnablement remplacer tes gardes d’inclusion par un simple "#pragma once".
    #pragma once
     
    #include "compte.h"
     
    #include <iostream>
     
    class Sauvegarde
    {
    public:
    	static void sauvegarde(const Compte & ccp, const Compte & livretA);
    	static void restitution(Compte & ccp, Compte & livretA);
    };


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // ...
    case 11 :
    	Sauvegarde::sauvegarde(ccp, livretA);
    // ...


    Je ne comprends toujours pas comment faire pour le 1 er cas .
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    case 11 :
    	Sauvegarde::sauvegarde(ccp, livretA);
    // ...

    Ceci est une implémentation , un appel de méthode ?
    Et pour ce qui est du sauvegarde.cpp , j'ai fait ca :

    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 "sauvegarde.h"
    #include "compte.h"
    #include <iostream>
    #include <fstream>
     
    using namespace std;
     
    static void sauvegarde(const Compte & ccp, const Compte & livretA)
    {
    	fstream file("sauvegarde.txt",ios::out);
    		  if(file.is_open())
    		  {
    			  file << ccp.getsolde()<< endl;
    	          file << livretA.getsolde()<<endl;
    			  file.close();
    			  cout << "solde enregistré avec succès" << endl;
    		  }else{
    			  cout << "solde non enregistré"<< endl;
    		  }
    		  cout << "Aurevoir" << endl;
    }
    static void restitution(Compte & ccp, Compte & livretA)
    {
    	fstream file("sauvegarde.txt",ios::in);
     
    	 	  if(file.is_open())
    	 	  {
    	 	       int input;
     
    	 	       file >> input;
    	 	       ccp.setsolde(input);
    	 	       file >> input;
    	 	       livretA.setsolde(input);
    	 	       file.close();
    	 	       cout << "solde lu avec succès" << endl;
    	 	  }else{
    	 		  cout << "solde non lu"<< endl;
    	 	  }
    }

    Mes yeux fatiguent et j'ai l'impression de faire que de la m....
    Pas question de faire l'impasse sur cet exemple , il faut que je comprenne

  11. #11
    Membre averti
    J’imagine que tu rencontres des problèmes de compilation liés au fait que la définition de tes méthodes de classe sauvegarde et restaure ne sont pas qualifiées et comportent le mot-clef static innaproprié dans leur définition (mais pas dans leur déclaration). En clair :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    static void sauvegarde(const Compte & ccp, const Compte & livretA) // Pas bon : définition d’une fonction statique.
    {
    	//...
    }
     
    void Sauvegarde::sauvegarde(const Compte & ccp, const Compte & livretA) // Bon : définition d’une méthode (statique ou non) de la classe Sauvegarde.
    {
    	//...
    }


    Pour mémoire (en C++, le mot clef static a 3 sens différents) :


    Fichier Truc.h
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void fonction(int x);
     
    class Truc
    {
    public:
    	static void methode_de_classe(int x);
     
    	void methode_d_instance(int x);
    }


    Fichier Truc.cpp
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void fonction(int x) {}
     
    // Pour les fonctions, une définition static signifie que la fonction n’est utilisable qu’au sein de la même unité de compilation (en gros ce fichier Truc.cpp).
    static void autre_fonction(int x) {}
     
    void Truc::methode_d_instance(int x)
    {
    	// Peut accéder à 'this'.
    }
     
    void Truc::methode_de_classe(int x)
    {
    	// Ne peut pas accéder à 'this'.
    }


    Fichier main.cpp
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main()
    {
    	fonction(42);
     
    	// autre_fonction(42);  => Le symbole 'autre_fonction' n’est pas exporté et n’est donc pas disponible dans l’unité de compilation de la fonction 'main'.
     
    	Truc::methode_de_classe(42);
     
    	Truc truc;
    	truc.methode_d_instance(42);
    }