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 :

Probleme de structure


Sujet :

C++

  1. #1
    Membre du Club Avatar de mouchT8
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 141
    Points : 49
    Points
    49
    Par défaut Probleme de structure
    Bonjour voici mon code (pas encore totalement finit..):

    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
    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<conio.h>
     
    #define LONGNOM 50	//longueur maximum d'un nom ou d'un prénom
     
    using namespace std;
     
    //**
    class Personne{
     
    private:	struct personne{
    			char nom[LONGNOM];
    			char prenom[LONGNOM];
    			int age;
    			}PERSONNE;
     
    struct personne *p;
     
    public:	Personne();		//Constructeurs
    		Personne(char);
    		~Personne();	//Destructeur
     
    		void affiche();
    		void modif_nom(char *);
    		void modif_prenom(char *);
    		void modif_age(int);
    };
     
    //CONSTRUCTEURS
    Personne::Personne(){
    PERSONNE.nom[1];
    PERSONNE.prenom[1];
    PERSONNE.age = 0;
    }
     
    //************
    Personne::Personne(char n) {
     
     
    }
     
    //DESTRUCTEUR
    Personne::~Personne(){
    delete p;
    }
     
    //Fonction AFFICHE
    void Personne::affiche(){
    	cout<<"Nom: "<<PERSONNE.nom<<endl;
    	cout<<"Prenom: "<<PERSONNE.prenom<<endl;
    	cout<<"Age: "<<PERSONNE.age<<endl;
    }
     
    //Fonction modif_nom
    void Personne::modif_nom(char *n){
    cout<<"Modification du nom: "<<endl;
    cin>>PERSONNE.nom;	
    }
     
    //Fonction modif_prenom
    void Personne::modif_prenom(char *n){
    cout<<"Modification du prenom: "<<endl;
    cin>>PERSONNE.prenom;
    }
     
    //Fonction modif_age
    void Personne::modif_age(int a){
    cout<<"Modification de l'age: "<<endl;
    cin>>PERSONNE.age;
    }
     
     
    void main(){
     
    struct personne MOI;
     
    cout<<"Affichage d'une fiche 'personne': "<<endl;
    MOI.affiche();
     
    getchar();
    }

    Voila j'aimerais pouvoir dans ma fonction main, initialiser donc une structure "MOI" grace aux fonction modif_nom, modif_prenom et modif_age .

    Le probleme qui se pose ici est que lorsque par exemple ici, je déclare ma
    "struct personne MOI",
    VS M'indique que "MOI" utilise une struct de 'main::personne' non définie.
    Il ne peut apparemment pas acceder à la structure de Personne...
    Je suis un peu perdue à vrai dire,
    quelqu'un pourrait t -il éclairer mon chemin ??

  2. #2
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Bon ton code comporte quelques erreurs :
    1 - tu declarre un pointeur p que tu n'initialise pas et tu fait un delete dessus.
    (Comme tu ne t'en sert pas je l'ai supprimé pour compiler)
    2 - Dans ton constructeur il faut initialiser tes chaines correctement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    PERSONNE.nom[0]=0;
    PERSONNE.prenom[0]=0;
    3 - Dans ton main il faut créer un objet du type de la classe :
    4 - Pour compiler j'ai supprimé le paramètre de tes fonctions membres vue que tu ne t'en sert pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    		void modif_nom();
    		void modif_prenom();
    		void modif_age();
    Ce qui fait dans le main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Personne MOI;
    MOI.modif_nom();
    MOI.modif_prenom();
    MOI.modif_age();
     
    cout<<"Affichage d'une fiche 'personne': "<<endl;
    MOI.affiche();

  3. #3
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 899
    Points : 1 916
    Points
    1 916
    Par défaut
    Bonjour.

    Bon, même avec mon peu d'expérience, j'ai quand même le sentiment que ton code est un construit au hasard. Je vais essayer de répondre à ta question, avant de faire quelques remarques plus générales.

    Quand tu appelles :
    dans le main, tu essaies de créer une structure qui n'est pas définie. En effet, 'personne' est définie au sein de la classe 'Personne'. Pour pouvoir créer une structure 'personne' en-dehors de la classe personne, il te faut effectuer une résolution de portée, avec l'opérateur '::', afin de récupérer cette structure 'personne' dans la classe 'Personne' :

    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
     
    class Personne{
    private:
        struct personne{ /* contenu de la structure */ };
        personne* _data;
    public:
        /* contenu de la classe */
    };
     
    int main()
    {
        Personne::personne* _MOI;
        /* code */
       return 0;
    }
    Cependant, dans ce code tu vas générer un autre erreur : la structure 'personne' est déclarée 'private' dans la classe 'Personne', par conséquent, on ne peut y accéder depuis l'extérieur de la classe. Pour pouvoir y accéder de l'extérieur, il faut procéder ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class Personne
    {
    public:
        struct personne{ /* contenu de la structure */ }; // Visible depuis l'extérieur de la classe
    private:
        personne* _data; // Visible uniquement dans la classe
        /* code de la classe */
    };

  4. #4
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Cependant, dans ce code tu vas générer un autre erreur : la structure 'personne' est déclarée 'private' dans la classe 'Personne', par conséquent, on ne peut y accéder depuis l'extérieur de la classe.
    On peut y acceder avec les fonctions membres de la classe. A condition de créer un objet de type class Personne.
    (ce n'est pas forcement bien de mettre toute les données membre public, et puis alors a quoi servirait les fonctions membres modif_ ...)

  5. #5
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 899
    Points : 1 916
    Points
    1 916
    Par défaut
    Ensuite, quelques remarques en vrac :

    Je remarque que tu mélanges allègrement du C et du C++, j'ai vu des std::cin d'un côté et un getchar() de l'autre, c'est rarement une bonne idée ; j'ai déjà eu l'occasion de constater en TP que certaines bibliothèques de base du C utilisent des niveaux différents pour les entrées/sorties qui peuvent poser problèmes entre elles.

    L'usage à outrance des macros est fortement déconseillé en C++, en dehors des cas où elles sont nécessaires comme pour les gardes d'inclusion. Utilise plutôt des constantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const int LONGNOM = 50;
    Par ailleurs, n'oublie qu'un tableau utilisé pour gérer les chaînes de caractères ne peut contenir que 'taille-1' caractères, car il faut toujours en avoir un pour placer la sentinelle de fin de chaîne '\0'. La SL propose d'ailleurs l'objet std::string pour gérer les chaînes de caractères de façon plus simple et plus sécurisée ; la fonction std::string::c_str() permet d'obtenir un tableau de caractères terminé par un '\0', s'il faut l'utiliser avec une fonction C.

    Si tu utilises une std:string pour des fonctions comme modifier_nom(), et que tu ne requiers pas des paramètre explicites, tu pourras utiliser cette fonction avec des std::string, avec des chaînes de caractère type C, ou avec des constantes chaînes de caractères ("David").

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Personne::modifier_nom(const std::string& nom)
    En effet, std::string dispose d'un constructeur qui prend une chaîne C en paramètre, par conséquent, si tu appelles ta fonction en lui passant une chaîne C ou une constante, le compilateur créera implicitement une std::string, qui sera elle passée à la fonction.

    Dans le main, ce n'est pas une structure personne qu'il te faut créer, mais une classe Personne, à moins que tu puisse utiliser une structure Personne::personne pour initialiser une classe Personne, ce qui requerra un constructeur approprié ( Personne(const & Personne::personne), par exemple).

    Pour les fonction qui ne modifient pas la classe, comme affiche(), mets les en const :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class Personne{
    /* code */
    public:
    void affiche() const;
    /* code */
    };
    Cela permettra à la compilation de vérifier qu'aucune instruction de la fonction, et qu'aucun appel à la fonction, n'entraîne une modification de l'objet personne sur lequel la fonction est appelée. C'est essentiellement un garde-fou, qui permet par exemple de se protéger de certains copier-coller "sauvages".

  6. #6
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 899
    Points : 1 916
    Points
    1 916
    Par défaut
    Citation Envoyé par Lucien63 Voir le message
    On peut y acceder avec les fonctions membres de la classe. A condition de créer un objet de type class Personne.
    (ce n'est pas forcement bien de mettre toute les données membre public, et puis alors a quoi servirait les fonctions membres modif_ ...)
    En fait, ce n'est pas exactement ce que je disais. Le principe d'encapsulation veut que le pointeur

    qui contient les informations d'un objet de la classe Personne soit déclaré private, afin qu'on ne puisse y accéder depuis l'extérieur.

    Cependant, le type du pointeur (Personne::personne) est déclaré à l'intérieur de la classe. Par conséquent si on veut créer un objet 'Personne::personne' à l'extérieur de la classe 'Personne', il faut que la structure 'personne' soit déclarée public dans la classe 'Personne'.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main()
    {
        Personne::personne p;
        /* code */
    }
    n'est pas possible si

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class Personne
    {
    private:
        struct personne { /* code */ };
        /* code */
    };

  7. #7
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Cependant, le type du pointeur (Personne::personne) est déclaré à l'intérieur de la classe. Par conséquent si on veut créer un objet 'Personne::personne' à l'extérieur de la classe 'Personne'
    Tout a fait, mais ça mouchT8 ne le précise pas.

Discussions similaires

  1. Probleme de structure d'un graphe
    Par Aurelienjjj dans le forum C
    Réponses: 11
    Dernier message: 20/11/2006, 16h41
  2. [XSLT] Probleme de structure de fichier xsl
    Par ben23 dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 17/07/2006, 10h46
  3. C++ - Probleme avec structure et template
    Par vdumont dans le forum Langage
    Réponses: 3
    Dernier message: 21/03/2006, 15h32
  4. Probleme taille structure / parsing tag mp3
    Par lucas_sophia dans le forum C
    Réponses: 6
    Dernier message: 19/03/2006, 16h56
  5. Réponses: 3
    Dernier message: 28/09/2003, 17h08

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