Forum Programmation.c++ fichier d'en tête fich.h

Posté par  .
Étiquettes : aucune
0
26
juin
2007
Bonjour à tous

voici mon code


#ifndef _BD_H_
#define _BD_H_
using namespace std;

class voiture
{
private: string nvhe;
string couleur;
string marque;
int km;
Personne *proprietaire;
public: voiture();
~voiture();
//voiture();
int rouler(int distance);
void enregistrer_vehicule(voiture *V1);
void afficher_vehicule(voiture *V1);
Personne *get_proprietaire(voiture *V1);
};

class Personne{
string nss;
string nom;
string prenom;
string datenaissance;
voiture *Veh;
public:Personne();
void enregistrer(Personne *P);
int viellir();
void afficher(Personne *P);
void dormir();
void posseder_voiture(Personne *P1);
int age();
};


j'obtiens après compilation:

In file included from BD.cpp
BD.h ISO C++ forbids declaration of `Personne' with no type
BD.h expected `;' before '*' token
BD.h ISO C++ forbids declaration of `Personne' with no type
BD.h expected `;' before '*' token
BD.cpp In constructor `voiture::voiture()':
BD.cpp `proprietaire' undeclared (first use this function)
BD.cpp 'class voiture' has no member named 'proprietaire'

je n'arrive pa à décoder ce message d'erreur.

aidez moi.

merci d'avance.
  • # alors...

    Posté par  . Évalué à 0.


    [1]
    In file included from BD.cpp
    BD.h ISO C++ forbids declaration of `Personne' with no type
    BD.h expected `;' before '*' token
    BD.h ISO C++ forbids declaration of `Personne' with no type
    BD.h expected `;' before '*' token

    [2]
    BD.cpp In constructor `voiture::voiture()':
    BD.cpp `proprietaire' undeclared (first use this function)
    BD.cpp 'class voiture' has no member named 'proprietaire'



    [1] il manque des choses dans ta definition de Personne

    [2] il ne trouve pas propriétaire, c'est normal cela n'est pas defini dans Personne
    • [^] # Re: alors...

      Posté par  (site web personnel) . Évalué à 2.

      Ton problème est un soucis de dépendances circulaire entre classe...

      Tu devrais régler ceci en rajoutant :
      class Personne;

      Avant :
      class voiture
      {
      ...
      };

      Comme ça il saura que la classe personne existe quand il entre dans la définition des membres de la classe voiture.
  • # Relis.

    Posté par  . Évalué à 4.

    Tu as déjà posé la question ici, et on t'a déjà répondu :

    https://linuxfr.org/forums/20/22392.html

    1) Faire des références mutuelles entre deux classes, çai mal. Je pense même qu'en Java, par exemple, ce ne serait pas possible (je me trompe peut-être, que les experts ne m'en veuillent pas). En général, cela traduit une erreur de conception.

    2) Tu ne peux bien sûr pas définir un objet de chaque type dans l'autre classe, par contre tu peux effectivement utiliser une référence ou un pointeur (ce qui est pratique pour les listes chaînées). Sauf qu'une classe étant définie après l'autre, au moment où tu définis « voiture », ton compilo ne sait pas encore que « Personne » est une classe, donc un type de données.

    Solution : utiliser des prototypes.

    class voiture;
    class Personne;


    class voiture { ...


    Mais je répète : les références circulaires, en général, sapuduku.
    • [^] # Re: Relis.

      Posté par  (site web personnel) . Évalué à 1.

      +1 à "déjà répondu" ... d'autant que pour une fois (que tu es chanceux!), j'ai donné le lien précis dans la FAQ de developpez.

      Par contre, les références circulaires ne me gêne pas plus que cela. J'ai vu des abus sur quantité de pièges à débutants en OO, mais ça, pas encore.
  • # Problème Objet

    Posté par  . Évalué à 2.

    En effet, le simple fait que ta structure objet ait 2 classes qui se référencent mutuellement n'est pas très sain :
    Demande toi plutôt dans quel rôle Voiture a besoin d'avoir une relation avec Personne ? Et dans quel rôle également Personne a besoin d'avoir une relation avec Voiture (au sens UML des termes).
    Réfléchis à tes cas d'utilisation et normalement tu devrais t'apercevoir que ce n'est pas forcément utile.
    Ce n'est pas vraiment un problème de langage mais plutôt un problème de méthodologie objet.
    • [^] # Re: Problème Objet

      Posté par  . Évalué à 1.

      exemple :
      -une voiture n'a pas forcément de propriétaire...elle peut très bien être encore chez le concessionnaire!
      -une personne n'a pas forcément de voiture...

      pour résoudre le problème d'une manière objet on peut suivre l'heritage suivant :
      Voiture <- VoitureAchetee
      Personne <- ProprietaireVoiture

      et les liaisons suivantes :
      VoitureAchetee -> Personne
      ProprietaireVoiture- > Voiture

      Ainsi, pas besoin de laison circulaire...
      • [^] # De charybde en scylla

        Posté par  (site web personnel) . Évalué à 0.

        Euh... je veux pas dire, mais là c'est bien pire.

        * Comment tu va réaliser la migration du type effectif de Voiture vers VoitureAchetee ? En recopiant chacun des champs ? Non ! Une voiture est une entité, en effectuant des copies, tu brises toutes les références à l'entité initiale.

        * Et comment obtenir une VoitureAchetee à partir d'un PriopriétaireVoiture ? En downcastant ? (si ça c'est pas un rejeton du démon.. :-/)

        Les liens bi-directionnels (0..*) existent, et ils ne sont pas le mal incarné. Il faut même leur reconnaitre un avantage : ils poussent à utiliser des déclarations anticipées ce qui améliore les temps de (re)compilation.

        Bon, avec un problème entièrement formulé, on pourrait proposer une modélisation correcte. Là, en partant sur des généralités, on va parler dans le vide.
        • [^] # Re: De charybde en scylla

          Posté par  . Évalué à 2.

          Je préfaire copier les champs effectivement, pour moi l'instance d'un objet n'est qu'une représentation modélisée, je ne vois pas le mal à devoir copier les attributs d'un objet. L'entité initiale on s'en tamponne, c'est les informations contenues dans l'objets qui sont importantes.

          De plus je ne vois pas l'intérêt d'obtenir les champs spécifiques à voiture achetée à partir du propriétaire, vu qu'elle ne font que repointer sur lui...totalement inutile, donc pas besoin de faire un downcast! que je ne n'aime pas plus que toi.

          D'ailleurs, la solution que je propose est grossomodo un state pattern, un des design pattern les plus connus...
          • [^] # Re: De charybde en scylla

            Posté par  (site web personnel) . Évalué à 2.

            C'est toute la différence, quand je manipule des entités (comme ici avec une hiérarchie polymorphe), j'ai les copies en horreur. Rien de tel pour perdre l'entité à chaque fois que son état doit évoluer -- sans parler de la complexité pour avoir une semantique de copie fiable sur des entités (polymorphes, c'est pire) en C++. Les valeurs, naitre et mourrir sans cesse est dans leur essence, les entités persistent et se lient.

            L'entité initiale, on ne s'en tamponne pas, c'est ce qui permet d'établir des liens entre les diverses entités du système (proprio, préfecture, voiture, auto radio, carte grise, moteur, roues, ...). À chaque mutation de type, c'est tous les liens que l'on doit retisser.

            Accessoirement, avec le state pattern on ne requalifie pas entièrement une entité, mais l'état d'une entité.

            Des champs spécifiques à la voiture achetée ....? Hum, la carte grise, le contrat d'entretien, la garantie, les références du vendeur, ... Chacune des classes peut être amenée à fournir cela à une tierce partie.

            Ou si tu préfères, tu prends une voiture et ses passagers. Un passager observe le monde voiture (chercherAutoradio) et agit eventuellement dessus (ouvrirPorte), la voiture va envoyer des feedbacks vers ses passagers (crash, ...).
            Tu ne va quand même pas avoir 2^4 classes de voitures pour chacun des passagers qui peut être ou ne pas être là tout de même ?
            • [^] # Re: De charybde en scylla

              Posté par  . Évalué à 2.

              Évidemment, c'est du bon sens, si la complexité du système à décrire s'emballe je ne ferais pas ça. Tu as raison. Je dirais même que c'est totalement pourri, je te l'accorde.
              Si le système est complexe, faut penser qu'il faudra le maintenir, et les liaisons redondantes, tu me l'accordera peut être, c'est pas non non plus la joie à maintenir si les proprio des voitures changent à tout va...
              Je proposerais donc ça à la place:

              Voiture
              -> modèle
              -> assurance
              -> carte grise
              -> contrat d'entretien
              -> etc

              mais pas de liens vers le Propriétaire

              Propriétaire :
              -> nom
              -> Voiture
              -> etc

              Système (singleton)
              -> proprietaires
              -> voitures
              - methode : rechercher_proprietaire_de_voiture()

              Bref, pas besoin de redondance. beaucoup plus propre que ce que j'ai proposé plus haut.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.