IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 :

Erreurs inconnues + questions


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Par défaut Erreurs inconnues + questions
    Bonsoir,
    J'aimerais que vous m'aidez à corriger le code suivant:
    UnePiece.h
    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
    #ifndef _UNEPIECE_H
    #define _UNEPIECE_H
    #include<string.h>
     
    class UnePiece
    {
    protected:
    	char *sonNom;
    public:
    	UnePiece(char *tel_ptr)
    	{
    		sonNom = NULL;
    		sonNom = new char[strlen(tel_ptr)+1];
    		strcpy(sonNom,tel_ptr);
    	};																																	}*/
    	~UnePiece()
    	{
    		delete[] sonNom;	
       };
    #endif
    UnePieceSimple.h
    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
    #ifndef _UNEPIECESIMPLE_H
    #define _UNEPIECESIMPLE_H
    #include "UnePiece.h"
    #include <string.h>
     
    class UnePieceSimple: public UnePiece
    {
    private:
       int son_poids;
     
    public:
    	UnePieceSimple(char *tel_ptr ,int tel_pds): UnePiece(tel_ptr), son_poids(tel_pds){}
     
       int donnePoids();
     
       void affiche(int);		
    };
     
     
    class UnePieceComposite :public UnePiece
    {
    private:
        UnePiece **sesComposants; // fin du tableau marquée par NULL
     
    public:
    	 UnePieceComposite(char *tel_ptrn , UnePiece **tel_ptrp) :
        UnePiece(tel_ptrn)
        {
    		int i,j;
    		for (i=0; tel_ptrp[i]; i++);
    	   sesComposants = new UnePiece*[i+1];
    	   for (j=0;j<=i;j++)
    	     sesComposants[j]=tel_ptrp[j];
        }
     
    	 int donnePoids();
     
    	 void affiche(int);
     
    	 ~UnePieceComposite ()
    	 {
    		delete []sesComposants;
    	 }
    };
    #endif
    UnePieceSimple.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
    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
    #include "UnePiece.h"
    #include "UnePieceSimple.h"
    #include <iostream>
    using namespace std;
    #include <string.h>
     
    int UnePieceSimple::donnePoids(){return son_poids;}
     
    void UnePieceSimple::affiche(int n)
    {
    	int i;
    	for (i=0; i<n; i++) 
         cout << "\t";
    	cout << son_nom << endl;
    }
     
     
    int UnePieceComposite::donnePoids()
    {
    	int som=0,i=0;
    	while(sesComposants[i] != NULL)
       {
    		som+=sesComposants[i]->donnePoids();
    		i++;
    	}
    	return som;
    }
     
     
    void UnePieceComposite::affiche(int n)
    {
       int i;
    	for(i=0;i<n;i++) 
         cout<<"\t";
    	cout << son_nom <<":"<< endl;
    	i=0;
       while(sesComposants[i] != 0)
       {
       	sesComposants[i]->affiche(n+1);
    		i++;
    	}
    }
    main.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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <cstdlib>
    #include <iostream>
    #include "UnePieceSimple.h"
     
    using namespace std;
     
    int main(int argc, char *argv[])
    {
     
        UnePieceSimple la_1("ecrou", 14);
        UnePieceSimple la_2("vis", 12);
        UnePiece **tab_1 = {&la_1, &la_2, NULL};
        UnePieceComposite la_3("appareil1", tab_1);
        UnePiece **tab_2 = {&la_1, &la_2, &la_3, NULL};
        UnePieceComposite la_4("appareil2", tab_2);
     
        la_4.donnePoids();
        la_4.affiche(1);
     
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    Est-ce que les fonctions donnePoids() et affiche(int) doivent être virtuelles? Moi je pense que oui parce que sesComposants est un tableau de pointeurs de type UnePiece sur des objets de types UnePieceSimple et UnePieceComposite.
    Y a-t-il une erreur avec les destructeurs? Je voulais le vérifier mais plusieurs erreurs dont la cause est ignorée sont apparues:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    3 C:\Users\user\Desktop\kk\UnePieceSimple.h:3,               from main.cpp In file included from UnePieceSimple.h:3,               from main.cpp 
    3 C:\Users\user\Desktop\kk\main.cpp                  from main.cpp
    15 C:\Users\user\Desktop\kk\UnePiece.h expected unqualified-id before '/' token 
    15 C:\Users\user\Desktop\kk\UnePiece.h expected init-declarator before '/' token 
    15 C:\Users\user\Desktop\kk\UnePiece.h expected `,' or `;' before '/' token 
     C:\Users\user\Desktop\kk\main.cpp In function `int main(int, char**)': 
    12 C:\Users\user\Desktop\kk\main.cpp initializer for scalar variable requires one element 
    14 C:\Users\user\Desktop\kk\main.cpp initializer for scalar variable requires one element 
     C:\Users\user\Desktop\kk\Makefile.win [Build Error]  [main.o] Error 1

  2. #2
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Salut

    Voici les erreurs que je vois, mais il est possible que certaines m'aient échappé

    - Il manque une accolade fermante après la définition du destructeur pour UnePiece.
    - Le compilateur indique qu'il a rencontré un '/' inattendu. Aurais-tu enlevé des commentaires de ce fichier ? Quoi qu'il en soit, vérifie que tu utilises bien un compilateur de C++, cette erreur me fait penser à un compilo C en mode ANSI.
    - Dans le constructeur de UnePieceComposite, tu as un for directement suivi d'un point virgule. Le compilo considère ça comme un for qui ne contient pas d'instruction.
    J'avais mal lu, mais tu aurais du donner un autre nom à la variable i, comme longueur ou len par exemple
    - Dans ton main, les deux lignes où tu crées des tableaux, remplace la définition de la variable par UnePiece* tab[ ], il est possible que le compilateur se formalise pour ça.

    Et voici quelques notes supplémentaires, fais en ce que tu veux.
    - c'est une mauvaise idée de mettre l'attribut "sonNom" en protected. Tu préféreras private.
    - il est inutile d'assigner NULL à sonNom, alors que juste après tu redéfinis sa valeur.
    - choisis des noms de variables plus explicites, sans quoi la relecture sera laborieuse voire même horrible. De plus, les variables nommées i et, dans une moindre mesure, j devraient être réservées à l'itération pure.
    - N'hésite pas à mettre des espaces et passages à la ligne pour séparer les groupes, ça aide grandement à la lecture. Idem pour l'indentation rigoureuse.

    Et pour répondre à tes questions sur les méthodes virtuelles, jamais un attribut de la classe ne justifierait des virtual.
    Les virtuals s'employent en cas d'héritage, pour pouvoir redéfinir ladite méthode dans la classe enfant. Or ici, aucune class n'hérite de UnePieceSimple, où sont définies ces deux méthodes.

    Ce que tu veux faire je crois, c'est définir des méthodes qui seraient accessibles dans tous les enfants de UnePiece. Dans ce cas, c'est dans UnePiece que tu dois déclarer ces méthodes comme étant virtuelles.

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Je n'ai pas le temps de tester le code pour trouver les erreurs syntaxiques (je fais confiance à Antoine_935) mais je te conseille de regarder du coté de la STL pour remplacer les char* par des std::string et tes tableaux de char* par des std::vector<std::string> (pour connaitre l'utilisation, cf la FAQ C++).

    Enfin, note que dans l'état actuel, il faut à ta classe un constructeur de recopie et un opérateur d'affection (ou alors les interdires) sans quoi, tu vas recevoir un segfault assez rapidement. Pour savoir comment faire une recherche sur le forum, google et la FAQ.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  4. #4
    Membre éclairé
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Par défaut
    Citation Envoyé par Antoine_935 Voir le message
    - Le compilateur indique qu'il a rencontré un '/' inattendu. Aurais-tu enlevé des commentaires de ce fichier ?
    Effectivement, il y avait un "*/" quelque part.
    Citation Envoyé par Antoine_935 Voir le message
    - Dans le constructeur de UnePieceComposite, tu as un for directement suivi d'un point virgule. Le compilo considère ça comme un for qui ne contient pas d'instruction.
    Pourquoi un for sans instructions est mal vu? Je l'ai utilisé pour calculé le nombre d'éléments du tableau à l'aide de i.
    Citation Envoyé par Antoine_935 Voir le message
    J'avais mal lu, mais tu aurais du donner un autre nom à la variable i, comme longueur ou len par exemple
    Le i est utilisé comme compteur dans for et au même temps il renseigne sur le nombre d'éléments du tableau.
    Citation Envoyé par Antoine_935 Voir le message
    - c'est une mauvaise idée de mettre l'attribut "sonNom" en protected. Tu préféreras private.
    sonNom est un champ de la classe mère qui sert aux classes filles. "Il doit être protected" c'est la règle, non?
    Citation Envoyé par Antoine_935 Voir le message
    - il est inutile d'assigner NULL à sonNom, alors que juste après tu redéfinis sa valeur.
    Tu as raison
    Citation Envoyé par Antoine_935 Voir le message
    Ce que tu veux faire je crois, c'est définir des méthodes qui seraient accessibles dans tous les enfants de UnePiece. Dans ce cas, c'est dans UnePiece que tu dois déclarer ces méthodes comme étant virtuelles.
    C'est exactement ce que je voulais dire. Je vais écrire l'affirmation suivante et je veux savoir si elle est correcte: "Quand on lance l'instruction suivante
    si la méthode affiche(int) est virtuelle avant de l'exécuter, le compilateur vérifie le type de l'objet sur lequel il va appliquer la méthode (puisque la_4 est composée de plusieurs pieces simples et composites) pour voir s'il va utiliser affiche(int) de UnePieceSimple ou bien de UnePieceComposite. Si affiche(int) n'est pas virtuelle et elle est définie dans UnePiece et surdéfinie dans UnePieceSimple et dans UnePieceComposite alors c'est la méthode de UnePiece qui sera exécutée car sesComposant est de type UnePiece**. Dans notre cas, puisque affiche(int) n'est définie que dans UnePieceSimple et dans UnePieceComposite va attendre la vérification du type de l'objet visé pour appliquer la méthode selon le type de l'objet."

    J'ai encore une dernière erreur: multiple types in one declaration. L'erreur est signalée pour la ligne qui contient l'accolade fermante de la déclaration de la classe UnePieceSimple.

    Finalement merci de tes conseils.

  5. #5
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Citation Envoyé par yo_haha Voir le message
    Pourquoi un for sans instructions est mal vu? Je l'ai utilisé pour calculé le nombre d'éléments du tableau à l'aide de i.
    C'est pas forcément "mal vu", c'est juste qu'après un for on attend au moins une instruction, par habitude. Au moins mets un commentaire au dessus pour avertir et dire ce qu'il fait.

    Le i est utilisé comme compteur dans for et au même temps il renseigne sur le nombre d'éléments du tableau.
    Oui, mais il représente plus la longueur du tableau que l'élément qu'on est en train de traiter. C'est un avis personnel évidemment.

    sonNom est un champ de la classe mère qui sert aux classes filles. "Il doit être protected" c'est la règle, non?
    Hehe, ça me rappelle un prof en début d'année :p Il avait crié parce qu'un élève avait suggéré de mettre un attribut en protected, au cours d'uml. On l'a pris pour un fou sur le moment même, mais mnt on se rappelle tous qu'un attribut protected c'est NAN !
    Bref non, pas d'attributs en protected, pour une raison simple: si un jour tu dois changer l'implémentation de la classe UnePiece et sa représentation du nom (pas bcp de chances dans ce cas, d'accord), tu devras retravailler les classes enfant.
    La solution est de mettre des méthodes publiques getNom() et éventuellement setNom() (getter / setter classique). Tu te serviras ensuite de ce getter dans la classe enfant quand tu as besoin du nom.

    C'est exactement ce que je voulais dire. Je vais écrire l'affirmation suivante et je veux savoir si elle est correcte: "Quand on lance l'instruction suivante
    si la méthode affiche(int) est virtuelle avant de l'exécuter, le compilateur vérifie le type de l'objet sur lequel il va appliquer la méthode (puisque la_4 est composée de plusieurs pieces simples et composites) pour voir s'il va utiliser affiche(int) de UnePieceSimple ou bien de UnePieceComposite. Si affiche(int) n'est pas virtuelle et elle est définie dans UnePiece et surdéfinie dans UnePieceSimple et dans UnePieceComposite alors c'est la méthode de UnePiece qui sera exécutée car sesComposant est de type UnePiece**. Dans notre cas, puisque affiche(int) n'est définie que dans UnePieceSimple et dans UnePieceComposite va attendre la vérification du type de l'objet visé pour appliquer la méthode selon le type de l'objet."
    Dans notre cas, le compilateur ne va tout simplement pas l'accepter, puisque sesComposants est un tableau de UnePiece, et que dans UnePiece il n'y a pas de méthode affiche(int).

    Donc oui, tu dois déclarer une virtuelle, éventuellement pure, dans UnePiece.

  6. #6
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Les getters/setter sont pas beaucoup mieux d'un point de vue conception te diront certains. Pour ce qui est du protected je partage pas l'avis de ton prof ...

  7. #7
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Citation Envoyé par Goten Voir le message
    Les getters/setter sont pas beaucoup mieux d'un point de vue conception te diront certains. Pour ce qui est du protected je partage pas l'avis de ton prof ...
    Si tu le dis, mais... explique ton avis.

Discussions similaires

  1. Erreur inconnue !
    Par dinver dans le forum C
    Réponses: 5
    Dernier message: 04/12/2005, 21h58
  2. erreur inconnue en VBA
    Par rapace dans le forum Access
    Réponses: 3
    Dernier message: 06/10/2005, 14h42
  3. erreur inconnue
    Par naw dans le forum Bases de données
    Réponses: 5
    Dernier message: 02/02/2005, 08h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo