Partage

Incrémentation dans Constructeur

17 août 2018 à 14:38:10

Bonjour, 

J'aimerais pouvoir incrémenter l'ID automatiquement lors de la création d'une instance Professeur mais cela ne fonctionne pas.

Cela reste à -10. 

Pourriez-vous m'aider ? Voici mon code: 

#include <iostream>
#include <string>
using namespace std;
struct Etudiant
{
	int id;
	string nom;
	void saisie();
	void affiche();
};

void Etudiant::saisie()
{
	cout << "Identifiant ? " << endl;
	cin >> id;
	cout << "Nom ? " << endl;
	cin >> nom;
}
void Etudiant::affiche()
{
	cout << "Identifiant : " << id << endl;
	cout << "Nom : " << nom << endl;
}

void supprime(Etudiant tab[], int &N);
void cherche(Etudiant tab[], int N);
void tri(Etudiant tab[], int N);

class Professeur
{
	int id;
	string nom;
public: void saisie();
		void affiche();
		string cherche( int);
		string getNom();
		Professeur();
		~Professeur();
		
};


void Professeur::saisie()
{
	/*cout << "Identifiant ? " << endl;
	cin >> id;*/
	cout << "Nom ? " << endl;
	cin >> nom;
}
void Professeur::affiche()
{
	cout << "Identifiant : " << id << endl;
	cout << "Nom : " << nom << endl;
}

void supprime(Professeur tab[], int &N);
string Professeur::cherche(int ide)
{
	if (ide == id)
	{
		affiche();
		return nom;
	}
	else
	{
		string none("erreur");

		return none;

	}
}
string Professeur::getNom()
{
	return nom;
}

Professeur::Professeur()
{
	cout << "id= " << id;
	static int compteur=-10;
	cout << compteur << endl;
	id = compteur; 
	compteur++;
	
}
Professeur::~Professeur()
{
	cout << "Dans le destructeur";
}


void main()
{
	int choix(0),Ne(0),Np(0),D(0);
	const int Nmax = 10;
	Etudiant eleve[Nmax];
	Professeur prof[Nmax];
	
	do 
	{
		cout << "1 pour eleves" << endl
			<< "2 pour prof" << endl;
		cin >> D;
		switch (D)
		{
		case 1:
		{
				do
				{
					cout << "1 : Ajouter au début et Affichage de tous les Etudiants" << endl
						<< "2 : Supprimer le début et Affichage du tableau" << endl
						<< "3 : Chercher un Etudiant selon son Id" << endl
						<< "4 : Tri selon NOM et Affichage du tableau" << endl
						<< "5: QUITTER" << endl;
					cin >> choix;

					switch (choix)
					{
					case 1:
					{
						Ne++;
						if (Ne > 1)
						{
							for (int i = Ne; i > 0; i--)
							{
								eleve[i] = eleve[i - 1];

							}

						}
						eleve[0].saisie();
						for (int i = 0; i < Ne; i++)
						{
							eleve[i].affiche();
						}

					}break;
					case 2:
					{
						supprime(eleve, Ne);
						for (int i = 0; i < Ne; i++)
						{
							eleve[i].affiche();
						}
					}break;
					case 3:
					{
						cherche(eleve, Ne);

					}break;
					case 4:
					{
						tri(eleve, Ne);
						for (int i = 0; i < Ne; i++)
						{
							eleve[i].affiche();
						}
					}break;

					}
				} while (choix != 5);
		}break;
		
		case 2:
		{
			do
			{
				cout << "1 : Ajouter au début et Affichage de tous les Profs" << endl
					<< "2 : Supprimer le début et Affichage du tableau" << endl
					<< "3 : Chercher un Prof selon son Id" << endl
					<< "4 : Tri selon NOM et Affichage du tableau" << endl
					<< "5: QUITTER" << endl;
				cin >> choix;

				switch (choix)
				{
				case 1:
				{
					Np++;
					if (Np > 1)
					{
						for (int i = Np; i > 0; i--)
						{
							prof[i] = prof[i - 1];

						}

					}
					prof[0].saisie();
					for (int i = 0; i < Np; i++)
					{
						prof[i].affiche();
					}

				}break;
				case 2:
				{
					supprime(prof, Np);
					for (int i = 0; i < Np; i++)
					{
						prof[i].affiche();
					}
				}break;
				case 3:
				{
					string nom("erreur");
					int id;
					bool trouve;
					
						
						do {
							cout << "id recherche? (0 pour quitter) " << endl;
							cin >> id;
							for (int i = 0; i < Np; i++)
							{

								nom = prof[i].cherche(id);
								if (nom == "erreur")
								{
									trouve = false;
									cout << "veuillez reesayer " << endl;
								}
								else
								{
									trouve = true;
									id = 0;
									cout << nom << endl;
									i = Np - 1;
								}
							}
						} while (id!=0);
						

				}break;
				
				case 4:
				{
					Professeur tmp;
					bool tri(false);
					
					while (tri == false)
					{
						tri = true;
						for (int i = 0; i < Np - 1; i++)
						{
							if (prof[i].getNom() > prof[i + 1].getNom())
							{
								tmp = prof[i];
								prof[i] = prof[i + 1];
								prof[i + 1] = tmp;
								tri = false;
							}
						}
					}
					for (int i = 0; i < Np; i++)
					{
						prof[i].affiche();
					}

				}break;

				}
			} while (choix != 5);
		}

		}


		
	
	} while (D != 0);
}

void supprime(Etudiant tab[],int &N)
{
	for (int i = 0; i < N; i++)
	{
		tab[i] = tab[i + 1];
	}
	
	
	tab[N].id = NULL;
	tab[N].nom = "";
	
	N--;
}

void cherche(Etudiant tab[], int N)
{
	int id;
	cout << "Id recherché ? " << endl;
	cin >> id;
	bool trouve(0);
	for (int i = 0; i < N; i++)
	{
		if (tab[i].id == id)
		{
			cout << tab[i].nom << endl;
			trouve = true;
		}

	}
	if (!trouve)
	{
		cout << "aucun match trouve" << endl;
	}
}

void tri(Etudiant tab[], int N)
{
	
	bool tri(true);
	
	while (tri==true)
	{
		tri = false;
		
		for (int i = 0; i < (N-1); i++)
		{
			if (tab[i].nom > tab[i + 1].nom)
			{
				string tmp;
				tmp = tab[i].nom;
				tab[i].nom = tab[i + 1].nom;
				tab[i + 1].nom = tmp;
				tri = true;
				
			}
		}
	}
}


void supprime(Professeur tab[], int &N)

{
	for (int i = 0; i < N; i++)
	{
		tab[i] = tab[i + 1];
	}
		
	N--;
}

Merci

Vous êtes demandeur d'emploi ?
Sans diplôme post-bac ?

Devenez Développeur web junior

Je postule
Formation
en ligne
Financée
à 100%
17 août 2018 à 15:16:42

Salut Paxb,

ton code n'est pas propre , met la main dans un fichier main.cpp la structure dans un .h et pour ta classe Professeur la déclaration dans le .hpp et instanciation dans un .cpp.

le compteur dans le constructeur est détruit a la fin de la création de ton objet .

Professeur.hpp

#include <iostream>

#ifndef PROFESSEUR_HPP
#define	PROFESSEUR_HPP

class Professeur {
public:
    Professeur();
    ~Professeur();
    void saisie();
    void affiche();
    std::string cherche(int);
    std::string getNom(){return nom;};
private:
    int id;
    std::string nom;
    static int compteur;
};

#endif	/* PROFESSEUR_HPP */

Professeur.cpp

int Professeur::compteur=-10; //valeur de basse attribuée au lancement du programme

Professeur::Professeur() :
id(compteur++)//l'incrementation(++) est apres le compteur se qui fait id = compteur;++compteur;
{
}

void Professeur::saisie(){
    std::cout << "Nom ? ";
    std::cin >> nom;
}

void Professeur::affiche(){
    std::cout << "Identifiant : " << id << std::endl;
    std::cout << "Nom : " << nom << std::endl;
}

std::string Professeur::cherche(int ide){
    if (ide == id)
        affiche();
    else
        return "erreur";
    return nom;
}

Professeur::~Professeur() {
    compteur--;//si compteur sert de savoir combien d'instanciation tu a ,pense a derementer a la destruction
    std::cout << "Dans le destructeur"<<std::endl;
}





-
Edité par di20 17 août 2018 à 15:23:33

17 août 2018 à 15:29:32

Merci di20,

Je sais que mon code n'est pas très clair mais le cours que j'ai demande que tout soit dans le main (pour le moment) et vu que je vais avoir examen, je m'y tiens.

Je créais plusieurs fichiers lorsque je suivais le cours ici (sur OC).

J'ai bien lu ta réponse et merci pour la rapidité. 

J'ai cependant toujours le même problème, à savoir mon id est à chaque fois de -10...

17 août 2018 à 15:44:15

Dans ton code de base, tu initialises la variable compteur à 10 à chaque constructeur. Normal que ce soit toujours la meme chose.

Maintenant, parlons de ton code. Pour commencer, pas de using namespace std en c++, j'ai pas de lien t'expliquant le pourquoi du comment, mais des recherches sur ce forum + google t'eclaireront sur ce sujet.

Et c'est moi ou tu fais un mélange de C/C++ ? Ce que tu veux faire releve de la POO mais tu utilises des struct (à bannir si tu fais de l'objet).

Tu sembles vouloir faire du C++ mais tu réinventes la roue en utilisant les tableaux statiques à la C..

Et enfin, sans vouloir être desagreable, ton cours a l'air d'etre encore pire que celui d'openclassroom : appatemment on t'encourages à écrire ton code dans un seul fichier, autorises le mélange C/C++ et les mauvaises pratiques liées au C++..

Un conseil : change de cours (celui de gbdivers ou de developpez.com pour le C++)

17 août 2018 à 15:46:59

Bonjour Dropper,

Je suis d'accord sur mon cours, cependant il fait partie d'une formation complète et je dois y passer.

Je pourrais vous passer les slides, vous comprendriez l'horreur. 

C'est ce que je me disais aussi sur l'initialisation dans chaque constructeur mais où pourrais-je alors l'initialiser ?

(Concernant les structures et le C, la première partie du cours porte là-dessus et la seconde sur l'POO. Je suis en cours du soir et ai donc des cours combinés de 2 années consécutives)

-
Edité par PaxB 17 août 2018 à 15:48:17

17 août 2018 à 15:53:50

PaxB a écrit:

C'est ce que je me disais aussi sur l'initialisation dans chaque constructeur mais où pourrais-je alors l'initialiser ?


une variable static : Et son petit exemple (piqué sur le net j'avoue, c'est plus propre et ça m'évite d'avoir à le faire moi-même :p)

Je te conseil aussi de mettre le cours d'OC de côté (au passage, j'en rajoute une couche !)

Pour ce qui est de tout mettre dans le main, tu ne devrais pas tarder à apprendre les différentes alternatives. Aucun soucis pour le moment, du moment que tu ne gardes pas cette habitude une fois que ton cours t'aura montré la bonne marche à suivre.

-
Edité par Sillimon 17 août 2018 à 16:01:21

17 août 2018 à 15:56:13

Lorsque je déclare static int compteur dans mes variables de classe, j'ai une erreur de compilation. 

17 août 2018 à 16:01:37

Tu dois rajouter une définition.

int Professeur::compteur;

Mais en C++17 on pourrait faire une variable inline

class Professeur {
private:
    static inline int compteur;
};




l'azerty est aux dispositions ce que subversion est aux SCM
17 août 2018 à 16:28:04

paxb j'ai testé mon code est il n'y a pas de problème .

code :

#include "Professeur.hpp"

int main(void) {
    Professeur a;
    Professeur b;

    a.affiche();
    b.affiche();

    return 0;
}

resultat :

Identifiant : -10
Nom : 
Identifiant : -9
Nom : 
Dans le destructeur
Dans le destructeur

RUN SUCCESSFUL (total time: 105ms)

tu a oublié

int Professeur::compteur=-10;

-
Edité par di20 17 août 2018 à 16:33:38

21 août 2018 à 5:01:19

@Dropper en c++ la différence entre class et struct, c'est l'accessibilité et la dérivation par défaut (private pour class, public pour struct), le reste c'est tout pareil. En c++, un struct peut avoir des constructeurs, un destructeur et des fonctions membres qui peuvent être virtuelles ou pas, des fonctions/variables membres qui peuvent être pubic/protected/private. struct supporte tous les types  de dérivation (héritage privé, public, multiple et même virtuel). En fait si j'écris:

struct Bar
{
   void foo();
};

C'est quasiment la même chose que si j'écrivais

class Bar
{
public:
   void foo();
};

Donc non, les struct ne sont pas à bannir si tu fais de l'objet, au contraire elles peuvent même être conceptuellement très utiles dans le cadre d'une bonne conception objet, le struct contient les données brutes, le class, les services à rendre par le programme. Une bonne conception objet doit se focaliser d'abord et avant tout sur les services à rendre, les classes doivent se focaliser non sur les données qu'elles encapsulent (qui n'ont aucun intérêt) mais sur les services qu'elles assurent. La notion centrale de la POO n'est pas l'encapsulation, c'est les services assurés par la classe. Tant que tu n'as pas compris ça, tu n'as rien compris à la POO.


-
Edité par int21h 21 août 2018 à 5:07:15

Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
21 août 2018 à 11:02:52

C'est exact, d'ailleurs il y en a toujours et encore des structs même dans la norme du C++.

Exemples:

l'azerty est aux dispositions ce que subversion est aux SCM
21 août 2018 à 11:23:30

Grosso merdo, ce que tu veux faire est un compteur d'instance.

On a pas bcp de choix pour cela:
- Une variable globale, mais cette dernière n'est aucunement liée à la classe, ce qui est sémantiquement très pauvre, donc on évite.
- Une variable membre statique, car elle "retient" sa valeur initiale.

Problème: Initialiser les variables membre statiques:
- On ne peut initialiser les membres statiques lors de la déclaration (sauf C++17).
- On ne peut appeler une fonction manuellement, tenir le compteur à jour reviendra de la responsabilité du programmeur et non de la classe.
- Le constructeur ne peut pas le faire, vu qu'il est appelé automatiquement à chaque instance, il écrasera systématiquement la valeur courante.
Donc, le seul moment qu'il nous reste pour agir est lors de l'implémentation.

Ce qui donne quelque chose comme suit:

// Déclaration:
struct machin
{
        // compte le total d'instances créées
    static unsigned totalInstance;
        // compte le nombre d'instances en vie
    static unsigned instanceAlive;
    machin();
    ~machin();
};

// Implémentation:
    // Initialisation des variables membre statiques
unsigned machin::totalInstance = 0;
unsigned machin::instanceAlive = 0;

    // Fonctions membre
machin::machin()
{
        // le constructeur incrémente les compteurs
    ++totalInstance;
    ++instanceAlive;
}

machin::~machin()
{
        // le destructeur decremente le compteur d'instances en vie
    --instanceAlive;
}

Et un programme de test pour visualiser tout cela:

int main()
{
    machin one;
    std::cout << "Apres creation 1er instance" << std::endl;
    std::cout << "total instances: " << machin::totalInstance << std::endl;
    std::cout << "instances en vie: " << machin::instanceAlive << std::endl;
    std::cout << "-------------------------\n" << std::endl;

    {
            machin two;
            std::cout << "Apres creation 2nd instance" << std::endl;
            std::cout << "total instances: " << machin::totalInstance << std::endl;
            std::cout << "instances en vie: " << machin::instanceAlive << std::endl;
            std::cout << "-------------------------\n" << std::endl;
    }

    std::cout << "Apres destruction 2nd instance" << std::endl;
    std::cout << "total instances: " << machin::totalInstance << std::endl;
    std::cout << "instances en vie: " << machin::instanceAlive << std::endl;
    std::cout << "-------------------------\n" << std::endl;

    {
        machin tree;
        std::cout << "Apres creation 3e instance" << std::endl;
        std::cout << "total instances: " << machin::totalInstance << std::endl;
        std::cout << "instances en vie: " << machin::instanceAlive << std::endl;
        std::cout << "-------------------------\n" << std::endl;
    }

    std::cout << "Apres destruction 3e instance" << std::endl;
    std::cout << "total instances: " << machin::totalInstance << std::endl;
    std::cout << "instances en vie: " << machin::instanceAlive << std::endl;
}
Note l'utilisation des blocks pour reduire la portée des variables (et les detruire au moment opportun).

-
Edité par Deedolith 21 août 2018 à 11:24:49

Incrémentation dans Constructeur

× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
  • Editeur
  • Markdown