Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 29/09/2009, à 16:50

arnaud_d

[Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

Bonjour,

J'ai appris le C/C++ il y a quelques années et j'essaie de m'y remettre. J'ai installé Anjuta et essaie de faire un programme très simple : déclarer une classe Humain, une classe Famille. Une Classe Famille comporte un tableau de pointeurs vers des Humains. Chaque Humain a un Nom et un Prenom.

Je déclare mes classes dans un fichier Classes.cc et les utilise dans un main.cc

Classes.h :

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */

#ifndef _CLASSES_H_
#define _CLASSES_H_

#define NbMMax 10

class Humain
{
public:
	Humain();   // Constructeur sans argument
	Humain(string nom, string prenom);

	void PutNom(string nom);
	void PutPrenom(string prenom);
	string GetNom();
	string GetPrenom();

private:
	string Nom;
	string Prenom;
};

class Famille
{
public :
	Famille();  // Constructeur de famille

	int GetNbMembres();
	void AjouteMembre(Humain* H);

private:
	int NbMembres;
	Humain* TabMembres[NbMMax];
};

#endif // _CLASSES_H_

Classes.cc :

#include <string>
using namespace std;
#include "Classes.h"
//#pragma hdrstop
//#pragma package(smart_init)

// ==== CLASSE HUMAIN ====
Humain::Humain()	// Constructeur de base de l'humain
{}

Humain::Humain(string nom, string prenom):Nom(nom),Prenom(prenom)
{}


// Fonctions d'accès aux données private (encapsulation controlée)
void Humain::PutNom(string nom)
{
	Nom=nom;
}

void Humain::PutPrenom(string prenom)
{
	Prenom=prenom;
}

string Humain::GetNom()
{
	return Nom;
}

string Humain::GetPrenom()
{
	return Prenom;
}

// ==== CLASSE FAMILLE ====
Famille::Famille():NbMembres(0)
{}

void Famille::AjouteMembre(Humain* H)
{
	TabMembres[NbMembres]=H;
	NbMembres++;
}

int Famille::GetNbMembres()
{
	return NbMembres;
}

et enfin main.cc :

#include "Classes.cc"
#include <iostream>

int main()
{
	ainee = new Humain("Dupont","Pierre");
	cadet = new Humain("Dupont","Paul");
	Famille FamilleDupont;
	FamilleDupont.AjouteMembre(ainee);
	FamilleDupont.AjouteMembre(cadet);
	printf("La famille compte %d membres", FamDupont.GetNbMembres());
	return 0;
}

J'obtiens les erreurs suivantes :

main.cc:25: error: ‘ainee’ was not declared in this scope
main.cc:26: error: ‘cadet’ was not declared in this scope
main.cc:30: error: ‘FamDupont’ was not declared in this scope

J'ai essayé de déclarer ainne, cadet, FamDupont autrement, je ne vois pas pourquoi ça marche pas.
Notez aussi que j'ai un doute sur la necessité ou non d'ajouter un using namespace std; et autres #pragma hdrstop (actuellement en commentaire).

Si vous voyez mon erreur ou même d'horribles habitudes, dites je serais ravi !

Merci beaucoup !

PS : en me relisant je pense que je devrais écrire FamDupont->GetNbMembres() au lieu de FamDupont.GetNbMembres()

Edit : j'avais oublié de définir Famille::GetNbMembres() dans Classes.cc

Dernière modification par arnaud_d (Le 29/09/2009, à 21:03)

Hors ligne

#2 Le 29/09/2009, à 16:56

omc

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

Bonjour,
quelques petits problemes de syntaxe

#include "Classes.hh" //il faut inclure les fichiers de déclaration
#include <iostream>

int main()
{
    Humain* ainee = new Humain("Dupont","Pierre"); //ainee est de type pointeur sur un Humain
    Humain* cadet = new Humain("Dupont","Paul");//pareil
    Famille FamilleDupont;
    FamilleDupont.AjouteMembre(ainee);
    FamilleDupont.AjouteMembre(cadet);
    printf("La famille compte %d membres", FamDupont.GetNbMembres()); //Sorties type C
    std::cout << "La famille compte "<<  FamDupont.GetNbMembres() << " membres" << std::endl; //Sorties type C++, c'est mieux quand on fait du C++ ;)
    
   //Destruction des objets créés dynamiquement avec l'operateur "new"
   delete ainee;
   delete cadet;

    return 0;
}

Je n'ai pas regardé le reste,
@ +

Dernière modification par omc (Le 29/09/2009, à 17:02)

Hors ligne

#3 Le 29/09/2009, à 16:59

omc

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

Re-bonjour,

arnaud_d a écrit :

PS : en me relisant je pense que je devrais écrire FamDupont->GetNbMembres() au lieu de FamDupont.GetNbMembres()

Il faut utiliser "->" lorsque la variable est un pointeur...
Là "FamDupont" est un objet à plat donc c'est bien "." pour faire appel à ces attributs...

Hors ligne

#4 Le 29/09/2009, à 17:05

arnaud_d

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

Merci beaucoup pour ta/tes réponses. Par contre je n'ai pas de fichier "Classes.hh" si bien que maintenant j'ai un

main.cc:20:22: error: Classes.hh: No such file or directory

et plein d'autres erreurs. J'ai jamais vu ces fichiers .hh et .cc c'est quoi ? J'étais habitué aux .cpp et .h (voire .hpp mais qui étaient ajoutés automatiquement par le logiciel sous Win à l'époque)

Hors ligne

#5 Le 29/09/2009, à 17:15

obiwankennedy

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

#include "Classes.h"


Dans mes logiciels, j'écris ton nom.
SGNGD: SvgGd is Not GD
Rolisteam

Hors ligne

#6 Le 29/09/2009, à 17:17

omc

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

OOps, je voulais parler de ton fichier de déclaration de tes classes, à savoir le fichier "Classes.h".
Mais tu peux le nommer comme tu veux, ce n'est qu'une question de convention, perso j'utilise .cprout-prout et .hprout-prout ... Pas trés original hmm

Dernière modification par omc (Le 29/09/2009, à 17:18)

Hors ligne

#7 Le 29/09/2009, à 17:52

arnaud_d

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

Bonjour obiwankennedy et merci pour ta participation.

C'est bien ce que je pensais mais en voyant la dose d'erreur que ça déclenchait j'ai penssé que tu parlais d'autre chose. En effet, si je fais comme vous me dites :

make famille
g++ -DHAVE_CONFIG_H -I. -I..  -DPACKAGE_LOCALE_DIR=\""/usr/local/share/locale"\" -DPACKAGE_SRC_DIR=\""."\" -DPACKAGE_DATA_DIR=\""/usr/local/share"\"    -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.cc
In file included from .../src/main.cc:20:
.../src/Classes.h:29: error: expected `)' before ‘nom’
.../src/Classes.h:31: error: ‘string’ has not been declared
.../src/Classes.h:32: error: ‘string’ has not been declared
.../src/Classes.h:33: error: ‘string’ does not name a type
.../src/Classes.h:34: error: ‘string’ does not name a type
.../src/Classes.h:37: error: ‘string’ does not name a type
.../src/Classes.h:38: error: ‘string’ does not name a type
main.cc: In function ‘int main()’:
.../src/main.cc:25: error: no matching function for call to ‘Humain::Humain(const char [7], const char [7])’
.../src/Classes.h:28: note: candidates are: Humain::Humain()
.../src/Classes.h:26: note:                 Humain::Humain(const Humain&)
.../src/main.cc:26: error: no matching function for call to ‘Humain::Humain(const char [7], const char [5])’
.../src/Classes.h:28: note: candidates are: Humain::Humain()
.../src/Classes.h:26: note:                 Humain::Humain(const Humain&)
make: *** [main.o] Error 1
Completed unsuccessfully
Total time taken: 0 secs

(j'ai remplacé le chemin par ... vous inquiétez pas)

A croire que je me sert mal des strings ?

Hors ligne

#8 Le 29/09/2009, à 17:57

arnaud_d

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

Oups c'est bon j'ai trouvé, je dois appeler <string> dans le main, avant l'appel de Classes.h afin qu'il puisse en "profiter".

Mais alors où est-ce que je dois le mettre ? Dans main.cc et Classes.cc, c'est pas un peu beauoucp ?

Vous confirmez l'usage du using namespace std; ?

Merci pour votre aide, j'y suis presque !

Hors ligne

#9 Le 29/09/2009, à 18:01

omc

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

Oui !
Il faut mettre la déclaration des headers quand tu en as besoins, ici plutot dans ton .hpp
Je m'explique :
Le compilo va commencer probablement (cela dépend comment tu as écris le makefile) par tenter de compiler "Classes.cpp", il va tomber sur #include "Classes.hpp", dans ton "Classes.hpp" il y aura #include<string> etc...

De toute façon tu peux abuser des includes systemes (#include<>), mais pas trop des include de tes fichiers (#include"") car dans ce dernier cas le compilo peut tourner en rond...

Dernière modification par omc (Le 29/09/2009, à 18:07)

Hors ligne

#10 Le 29/09/2009, à 18:02

arnaud_d

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

Donc appel de string dans main.cc et Classes.cc ?

et
#pragma hdrstop
#pragma package(smart_init)

vous en pensez quoi ?

Dernière modification par arnaud_d (Le 29/09/2009, à 18:03)

Hors ligne

#11 Le 29/09/2009, à 18:09

omc

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

houlà !!!
C'est la grosse artillerie ! Stop ! smile

Hors ligne

#12 Le 29/09/2009, à 18:19

arnaud_d

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

lol je sais même pas ce que c'est, ça sort de mes programmes d'antan !
Tu m'as pas répondu pour la déclaration de string dans les deux fichiers à la fois...

(en tous cas avec les deux ça marche). Dès que tu m'as répondu je poste la version finale de ce petit programme bien pourri mais qui rafraichit la mémoire smile

Dernière modification par arnaud_d (Le 29/09/2009, à 18:20)

Hors ligne

#13 Le 29/09/2009, à 19:14

omc

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

si..si, regarde au dessus, on a posté en même temps...

Hors ligne

#14 Le 29/09/2009, à 21:03

arnaud_d

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

Ah oui au temps pour moi smile
Merci beaucoup pour ton aide, tu m'as remis sur le bon chemin.

Chose promise chose due (avec une petite amélioration):

//Classes.h
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * classes.cc
 * Copyright (C) arnaud_d 2009 <>
 * 
 * classes.cc is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * classes.cc is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _CLASSES_H_
#define _CLASSES_H_

#define NbMMax 10

class Humain
{
public:
	Humain();   // Constructeur sans argument
	Humain(string nom, string prenom);

	void PutNom(string nom);
	void PutPrenom(string prenom);
	string GetNom();
	string GetPrenom();

private:
	string Nom;
	string Prenom;
};

class Famille
{
public :
	Famille();  // Constructeur de famille

	int GetNbMembres();
	void AjouteMembre(Humain* H);

private:
	int NbMembres;
	Humain* TabMembres[NbMMax];
};

#endif // _CLASSES_H_
// Classes.cc
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * classes.cc
 * Copyright (C) arnaud_d 2009
 * 
 * classes.cc is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * classes.cc is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#include <string>
using namespace std;
#include "Classes.h"
//#pragma hdrstop
//#pragma package(smart_init)

// ==== CLASSE HUMAIN ====
Humain::Humain()	// Constructeur de base de l'humain
{}

Humain::Humain(string nom, string prenom):Nom(nom),Prenom(prenom)
{}


// Fonctions d'accès aux données private (encapsulation controlée)
void Humain::PutNom(string nom)
{
	Nom=nom;
}

void Humain::PutPrenom(string prenom)
{
	Prenom=prenom;
}

string Humain::GetNom()
{
	return Nom;
}

string Humain::GetPrenom()
{
	return Prenom;
}

// ==== CLASSE FAMILLE ====
Famille::Famille():NbMembres(0)
{}

void Famille::AjouteMembre(Humain* H)
{
	TabMembres[NbMembres]=H;
	NbMembres++;
}

int Famille::GetNbMembres()
{
	return NbMembres;
}
// main.cc
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * main.cc
 * Copyright (C) arnaud_d 2009
 * 
 * main.cc is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * main.cc is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string>
using namespace std;
#include "Classes.h"
#include <iostream>

int main()
{
	Humain* ainee = new Humain("Dupont","Pierre");
	Humain* cadet = new Humain("Dupont","Paul");
	Famille FamilleDupont;
	FamilleDupont.AjouteMembre(ainee);
	FamilleDupont.AjouteMembre(cadet);
	std::cout << "La famille compte "<<  FamilleDupont.GetNbMembres() << " membres" << std::endl;
	std::cout << "Le plus jeune s'appele "<<  cadet->GetPrenom() << std::endl;
	std::cout << "Le plus vieux s'appele "<<  ainee->GetPrenom() << std::endl;

	//Destruction des objets créés dynamiquement avec l'operateur "new"
	delete ainee;
	delete cadet;
	return 0;
}

Hors ligne

#15 Le 29/09/2009, à 21:26

Link31

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

#include <string>
using namespace std;
#include "Clas

Le "#include <string>" doit aller dans le .h, puisque le .h utilise std::string. C'est également inutile de le remettre dans le .cc.

Mais le "using namespace std;" ne doit SURTOUT PAS aller dans le .h (dans l'idéal, il devrait même disparaître du .cc). Dans le .h, les "string" doivent donc devenir "std::string".

Évite au maximum les #define CONSTANTE, surtout dans les .h. Il vaut mieux utiliser (dans le .h) :

static const std::size_t NbMMax = 10;
Humain* TabMembres[NbMMax];

Hors ligne

#16 Le 30/09/2009, à 08:23

omc

Re : [Résolu] Petit coup de main à qqun qui se remet au C++ svp :)

Pour remettre une couche sur ce que dis Link31, il vaut mieux en général éviter les "using namespace" même si cela s'avère pratique.
De toute façon les bons éditeurs de code possède la complétion automatique...

Content de t'avoir aider,
@ Bientôt.

Juste une petite remarque:
Il est judicieux de déclarer const les méthodes qui ne modifie pas ta classe. Par exemple ce sont tout les Get...():

// string Humain::GetPrenom()
// devient
string Humain::GetPrenom() const
//ou encore si tu veux gagner un peu de mémoire et de temps CPU en évitant la recopie de l'objet string
const string& Humain::GetPrenom() const

Comme cela le compilateur verifiera (faut en profiter, il ne se trompe jamais) que ta méthode ne modifie pas ton objet...

Dernière modification par omc (Le 30/09/2009, à 08:31)

Hors ligne