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 :

Utilisation de Pointeurs


Sujet :

C++

  1. #1
    Membre éclairé Avatar de 3logy
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2007
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Août 2007
    Messages : 280
    Par défaut Utilisation de Pointeurs
    Salut Bonjour!!! J'ai ecrit le code suivant....

    Il recoit le nom prenom et le numero matricule d'un etudiant entre par l'utilisateur et le resort sur un tableau....si l'utilisateur entre le caractere '-'...dans le Nom il sort du programme....dans cet exemple j'ai juste pris un etudiant en exemple.

    Lorsque je compile je recoit un message d'erreur comme quoi:
    - nom prenom et matricule sont private....

    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
    84
    85
    #include<iostream>
    #include<string>
     
    using namespace std;
     
    class Teilnehmer {                 //Anfang der Klasse deklaration
    public:                          // Begin des Öffentlichen Abschnitts
    Teilnehmer();                    //Deklaration der standard Konstruktor
    ~Teilnehmer();                   //Deklaration der standard destruktor
    void Set (char Nachname[], char Vorname[], int Matrikelnummer);   // Zugriffsfuntion
    void print();
     
    private:		                 // Beginn des Privaten Abschnitts
    int   Matrikelnummer_in;              //Elementvariable
    char  Vorname_in[30];
    char  Nachname_in[30];
    };
     
    Teilnehmer::Teilnehmer(){     //Definition der standard konstruktor
        int  Matrikelnummer = 0;         // Initialisation der variable Matrikelnummer
        char Vorname = {'0'};           // Initialisation der variable Vorname
        char Nachname = {'-'};          // Initialisation der variable Nachname
        {
            cout << "Konstruktor \n";
        }
    }
     
    Teilnehmer::~Teilnehmer(){}      //deklaration der destruktor
     
    void Teilnehmer:: Set(char Nachname[], char Vorname[], int Matrikelnummer ){    //Definition eine funktion des klasses
    	 char  Nachname_in[30];
    	 char  Vorname_in[30];
    	 int   Matrikelnummer_in;
     
    	 *Nachname_in = *Nachname;
    	 *Vorname_in = *Vorname;
         Matrikelnummer_in =  Matrikelnummer;
     
     
     
     
    }
     
    void Teilnehmer::print(){
    	  Teilnehmer *COLLEGE;
     
     
    	  cout << "------------------------------------------------------------------------------------"<<endl;
    	  cout << "*                   |                                     |                        *"<<endl;
    	  cout << "*    Nachname       |              Vorname                |     Matrikelnummer     *"<<endl;
    	  cout << "*                   |                                     |                        *"<<endl;
          cout << "------------------------------------------------------------------------------------"<<endl;
     
    	  cout<< COLLEGE->Nachname_in << COLLEGE->Vorname_in << COLLEGE->Matrikulnummer_in;
    	  cout<<endl;
     
    }
     
     
     
    int main (){
     
    	int i = 0;                 // Deklaration un initialisation eine Ganzahl
        Teilnehmer *COLLEGE = new Teilnehmer;
        char Nachname[30];
        char Vorname[30];
        int Matrikelnummer = 0;
    	while(i<1){                 //Eingabe des Teilnehmers Daten Wenn Beim Nachname keine Minus Zeichen gibt
     
    	cout << "Geben Sie Bitte  Nachname, Vorname und die MatrNr. des "<< i <<". Teilnehmers ein: " << endl;
    	cin >> Nachname;
    	if( *Nachname != '-'){
    	cin >> Vorname;
    	cin >> Matrikelnummer;
    	COLLEGE[i].Set(char Nachname[], char Vorname[], int Matrikelnummer);
    	i++;
    	}
     
    	else break;
     
    	}
     
        print();
    	return 0;
    }

    Comment resourdre ce probleme? Merci pour l'aide!!

  2. #2
    Membre Expert Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    Ta fonction print ne va pas du tout.
    Pourquoi tu redéclares une classe !!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void Teilnehmer::print(){
     
     
    	  cout << "------------------------------------------------------------------------------------"<<endl;
    	  cout << "*                   |                                     |                        *"<<endl;
    	  cout << "*    Nachname       |              Vorname                |     Matrikelnummer     *"<<endl;
    	  cout << "*                   |                                     |                        *"<<endl;
          cout << "------------------------------------------------------------------------------------"<<endl;
     
    	  cout<< Nachname_in << Vorname_in << Matrikulnummer_in;
    	  cout<<endl;
     
    }
    Tu es dans une méthode mebre de ta classe, tu as juste à afficher ses valeurs.

  3. #3
    Membre éclairé Avatar de 3logy
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2007
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Août 2007
    Messages : 280
    Par défaut
    Oui merci mais j'ai toujours la mm erreur avec
    :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	 COLLEGE[i].Set(char Nachname[], char Vorname[], int Matrikelnummer);
    Code::blocks me donne l'erreur : expected primary-expression before "char"

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    1/Ta variable s'appelle Matrikelnummer_in et non Matrikulnummer_in.
    2/ L'appel d'une fonction, ce n'est pas COLLEGE[i].Set(char Nachname[], char Vorname[], int Matrikelnummer); mais COLLEGE[i].Set(Nachname, Vorname, Matrikelnummer);
    3/ Dans Teilnehmer::print, COLLEGE n'est pas initialisé.
    Peut-être devrais-tu commencer par faire un tour du côté des tutos. Il me semble que ton code traduit des lacunes importantes.
    Cordialement.

  5. #5
    Membre chevronné Avatar de AL1986
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 434
    Par défaut
    Salut,

    Dans ta classe tu as trois attributs private, pourquoi ne les manipules-tu pas dans le constructeur et la méthode Set au lieu de déclarer de nouvelles variables. Un constructeur est censé initialiser (ou pas) tes attributs, chose qui n'est pas faite par ton constructeur, tu déclares de nouvelles variables. Pareil pour Set dans laquelle tu déclares de nouveaux tes attributs alors qu'il faut juste leur donner des valeurs.

  6. #6
    Membre éclairé Avatar de 3logy
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2007
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Août 2007
    Messages : 280
    Par défaut
    Merci Archy!! J'y vais un tour!! ... J'ai retouche le code...

    En fait... si mon compilateur me dit char Teilnehmer::Nachname_in[30] is private... que dois je faire?

  7. #7
    Membre très actif
    Avatar de buggen25
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    554
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Août 2008
    Messages : 554
    Par défaut Private
    Bonjour;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    private :
    int   Matrikelnummer_in;              //Elementvariable
    char  Vorname_in[30];
    char  Nachname_in[30];
    Je pense que quand on déclare des variables de type privé ( private ) il faut rajouter des accesseurs.

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par buggen25 Voir le message
    Je pense que quand on déclare des variables de type privé ( private ) il faut rajouter des accesseurs.
    Si c'est pour systématiquement rajouter des accesseurs, c'est que les variables ne sont pas private! Il faut se poser la question en conception pourquoi doit-on accéder directement à ces variables à l'extérieur de la classe. Normalement, la classe doit offrir le service permettant d'être dans l'état souhaité.

  9. #9
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Utilise std::string.

  10. #10
    Membre très actif
    Avatar de buggen25
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    554
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Août 2008
    Messages : 554
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Si c'est pour systématiquement rajouter des accesseurs, c'est que les variables ne sont pas private! Il faut se poser la question en conception pourquoi doit-on accéder directement à ces variables à l'extérieur de la classe. Normalement, la classe doit offrir le service permettant d'être dans l'état souhaité.
    Salut, ça parait vrai, et je suis d'accord, la plus part des classes MFC, ou autre possède des "GETTERS" comme CDC *CWnd::GetDC() ... etc.
    Le principe n'est pas de declarer des accesseurs de type public ( ce qui correspond a ton poste ), mais plutot des accesseurs de type protected qui ne seront accessible que des membre de cette meme classe et les classes de type friend (amie). donc pas tout le temps accessible.

    Cordialement

  11. #11
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par buggen25 Voir le message
    Salut, ça parait vrai, et je suis d'accord, la plus part des classes MFC, ou autre possède des "GETTERS" comme CDC *CWnd::GetDC() ... etc.
    Modulo deux remarques: La première (troll en puissance): il y aurait beaucoup à redire sur les MFC. Mais, la seconde (plus pertinente), ce sont souvent des accesseurs pertinents: ainsi CWnd::GetDC() construit un CDC à partir d'un HDC (si je ne m'abuse).

  12. #12
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    En fait, créer un accesseur peut, pour ainsi dire, se faire sans se poser de question...

    Si la classe doit fournir le service de renvoyer cette valeur (que nous aurons pris la précaution de rendre constante, dans une méthode constante), il est tout à fait normal de ne pas limiter les services rendus par la classe.

    C'est la création d'un mutateur (setXXX ) qui devrait nous inciter à nous poser la question de savoir s'il est réellement opportun de placer le membre en accessibilité privée.

    D'un autre côté, il peut très bien s'agir d'apporter une certaine homogénéité dans le code: avec un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
        MonType t;
        cout<<t.getMembre();
        t.autreMembre = 6;
        cout<<t.autreMembre;
        return 0;
    }
    nous avons en effet tot fait de nous embrouiller quant à savoir s'il faut utiliser l'accesseur, ou s'il est possible d'accéder directement à un membre donné.

    D'un autre coté, même si c'est pour fournir un accesseur ET un mutateur pour un membre, le fait de rendre ce membre privé présente un avantage de taille: il n'y a qu'un nombre limité de points d'accès en modification de la valeur de ce membre. Cela facilite la gestion de la "compatibilité ascendante" (le fait qu'un code écrit en utilisant une version plus ancienne puisse continuer à travailler avec la version plus récente)

    Cela signifie que, si tu décide de modifier la représentation en mémoire du membre, tu n'aura que le corps d'une méthode à modifier, en gardant (souvent) le même prototype de fonction, et que tu ne devra pas commencer à courir dans tout le code pour retrouver l'ensemble des fonctions dans lesquelles tu es susceptible de modifier la valeur du membre.

    Un exemple tout bête est la décision (que je soutiendrai toujours) de remplacer un tableau "C Style" par un std::vector (ou une std::string s'il s'agit de gérer un tableau de caractères).

    Avec le tablea "C style", en acces public, tu pourrais te retrouver avec quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void foo()
    {
        MaClass c;
        c.tab = new type[10];
        c.tab[i] = /*...*/;
    }
    qui peut se retrouver littéralement partout (y compris dans du code dont tu ignore l'existence, si tu crée une bibliothèque)...

    Si, d'une version à l'autre, tu viens à décider de remplacer tn type* tab par un std::vector<type>, car, il n'y a rien à faire, l'utilisation d'un std::vector est bien plus sécurisante, dieu seul sait jusqu'où tu trouvera des fonctions à modifier, dans ton code, mais aussi dans le code des utilisateurs de ta bibliothèque.

    Alors que, si, dés le départ, tu avais mis ton membre tab en accessibiliité, meme avec une méthode dont le prototype est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const type* getTab() const;
    il te suffirait de modifier le corps de la fonction de
    en ou de remplacer le corps de la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void addElement(/*...*/)
    {
        type* ntab = new type[tabSize+1];
        std::copy(tab[0],tab[tabSize],ntab);
        delete tab;
        tab = ntab;
        tabSize++;
     
    }
    que tu aurais fatalement rajoutée en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void addElement(/*...*/)
    {
        tab.push_back(/*...*/);
    }
    pour que personne ne se rende sans doute jamais compte que tu as effectué la modification
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  13. #13
    Membre très actif
    Avatar de buggen25
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    554
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Août 2008
    Messages : 554
    Par défaut On peut utiliser la force brute
    Salut;
    Je savait pas qu'on pouvait acceder a un membre privé de cette manière
    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
    #include <stdio.h>
    class fraude1{
     
          int m_iVal;
     
    public :
          fraude1(){
                   m_iVal = 1;
                   };
          };
    class fraude2{
     
    public : 
          fraude2(){      };             
          int m_iVal;
          int getVal(){return m_iVal;};
     
    };
    int main(int argc,char * argv[])
    {
     
        fraude1 frd1;
        fraude2 *frd2 = reinterpret_cast<fraude2*> (&frd1);
        printf("%d",frd2->m_iVal);
        scanf("%d");
        return 0;
    }
    Donc on peut frauder ? et rendre les termes private, public, et protected completement insensé.
    Cordialement !

  14. #14
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    A vrai dire, c'est tout le problème du transtypage "sauvage", qu'il soit effectué "à la manière C" sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void foo()
    {
        int *ptrInt = new int;
        float *ptrFloat =(float*) ptrInt;
    }
    ou "à la manière C++" sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void foo()
    {
        int *ptrInt = new int;
        float *ptrFloat =reinterpret_cast<float*> (ptrInt);
    }
    Quand tu écris un tel code, cela revient à dire au compilateur
    Tu croyais que la variable était un (type d'origine), hé bien, détrompe toi (ou peut etre est ce moi qui me trompe ) mais je veux l'utiliser comme s'il s'agissait du (type de destination)
    Le fait est que le compilateur est un "brave petit soldat", et qu'il ne discute jamais un ordre donné par son "supérieur", pour autant que l'ordre ne le mette pas en position de s'écarter des règles qui lui sont imposées:

    Pour lui, si tu décide de "faire passer" une variable d'un type donné pour un autre, c'est que tu as tes raisons

    Donner cet ordre au compilateur revient le plus souvent à vouloir jouer à la roulette russe, dans le sens où tu te dirige droit vers l'erreur de segmentation (ou du moins vers la tentative d'accéder à une adresse incohérente):
    • si les membres (de même nombre et de même type) sont - tout simplement - déclarés dans un autre ordre entre les deux types ou
    • si les membres sont eux même des type non POD, compatible (par héritage, par exemple) mais différents, ou encore
    • si le nombre ou le type des membre est différent
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  15. #15
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Ou encore s'il y a un truc auquel tu n'avais pas pensé, genre une des classes a des fonctions virtuelles et pas l'autre...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 14
    Dernier message: 22/04/2006, 21h59
  2. Optimiser l'utilisation des pointeurs
    Par progfou dans le forum C
    Réponses: 65
    Dernier message: 10/03/2006, 11h49
  3. Réponses: 6
    Dernier message: 21/02/2006, 16h47
  4. Utilisation de pointeurs
    Par renard s dans le forum Débuter
    Réponses: 7
    Dernier message: 08/12/2005, 08h18
  5. Utilisation de Pointeurs dans API windows
    Par Drooxy dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 13/03/2003, 22h39

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