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 :

Problème avec l'opérator []


Sujet :

C++

  1. #1
    Membre habitué Avatar de b Oo
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 179
    Points : 185
    Points
    185
    Par défaut Problème avec l'opérator []
    Bonjour à tous,
    j'ai un petit problème pour redéfinir l'opérateur []. Je vous donne le code qui ne fonctionne pas :
    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
     
    class B
    {
      public :
       B(B**);
       ...
       void getVal() const { return _valeur; }
     
      private:
       int _valeur;
       B ** _p;
    };
     
    B::B(A * p=0):_valeur(0), _p(p)
    {
    }
    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
     
    class A
    {
      public :
       A();
       ...
       B * operator[](int i) { return tab[i]; }
     
      private :
       B* tab[81];
    };
     
     
    A::A()
    {
       for (int i = 0; i < 81; ++i)
         tab[i] = new B(tab+i);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    ...
    int main()
    {
      A a;
      A * pa = &a;
      cout << pa[0] << endl; // pas valide à mon avis
      cout << (*pa)[0] << endl; // valide à mon avis
     
      ...
    };
    J'aimerais savoir comment définir l'opérateur [] pour que pa[0] soit valide et que a[0] soit valide aussi, si cela est possible.

    Edit :
    Question reformulée.

    Merci d'avance.

    b Oo
    b Oo

  2. #2
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Ce me parait bizarre. De même que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tab[i] = new B(tab[i]);
    qui :
    - ne devrait pas compiler vu tes déclarations
    - t'aurait exposé à la figure vu que la valeur de tab[i] n'est pas déterminée au moment de l'appel (en supposant qu'il y ait un constructeur B(B*)). Cela passerait avec un B(*&), mais comment dire que je te déconseille fortement une telle chose.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  3. #3
    Membre éclairé Avatar de reggae
    Profil pro
    Inscrit en
    Août 2005
    Messages
    773
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2005
    Messages : 773
    Points : 795
    Points
    795
    Par défaut
    Te manque un point-virgule à la fin de ta classe A.

  4. #4
    Membre habitué Avatar de b Oo
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 179
    Points : 185
    Points
    185
    Par défaut
    Oui Luc, il n'y avait pas de problème à la compilation avec g++ version 4.03.

    En fait ce qui ce passait avant que j'edit le post, c'est que lorsque je crée mon tableau, chaque élément est défini et pointe sur n'importe quoi.
    tab[i] est donc "déterminé" mais il ne possède pas ce que je veux.

    Donc maintenant, j'ai ma classe A qui contient 81 cases qui chacune pointe sur un objet B, et chaque objet B pointe sur la case du tableau où il a été construit et a une valeur de 0.
    Maintenant je pense que le code est moins "bizarre".

    Par contre pour l'opérateur [], je voudrais savoir si on peut faire cela :

    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
     
    class A
    {
      public :
       A();
       ...
       int * operator[](int i) { return tab[i]; }
     
      private :
       int * tab[81];
    }; 
     
    int main()
    {
       A a;
       A * pa = &a;
       cout << pa[0] << endl; // pas valide à mon avis
       cout << (*pa)[0] << endl; // valide à mon avis 
      ...
    }
    J'aimerais savoir comment définir l'opérateur [] pour que pa[0] soit valide et que a[0] soit valide aussi, si cela est possible.

    Merci.

    b Oo
    b Oo

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 76
    Points : 61
    Points
    61
    Par défaut
    en disant "que pa[0] soit valide et que a[0] soit valide aussi" je suppose que tu veux dire qu'il devrai avoir le même effet.

    si c'est le cas, je ne pense pas que se soit une bonne idée.
    pa est un A*, quand tu utilise l'opérateur [i] dessus, je m'imagine plutot que tu essai d'accéder au ième élement, d'un tableau de A; tableau nommée pa.
    en voulant changé cet opérateur, le code risque d'être difficilement compréhensible par une autre personne.

    deux choses que je croit vrai mais qu'il faudrai vérifier:
    - (*pa)[i] est équivalent à *pa[i]

    - le moyen de quand même surcharger ton opérateur serai d'écrire cette fonction ces 2 fonctions:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class A{
      public:
        int operator[](int i);
      ...
    };
     
    int operator[](A* a, int i){
      return a->operator[](i);
    }
    je reste quand même convaincu que ce n'est pas une bonne idée.
    2 n'est pas égal à 3, même pour de grandes valeurs de 2 ou de petites valeurs de 3

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    tu es sûr que ça marcherait ? ni A* ni int ne sont des types utilisateur: Je crois que pour surcharger un opérateur, une des opérandes au moins doit être d'un typê utilisateur...
    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.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 76
    Points : 61
    Points
    61
    Par défaut
    comme je l'ai dit, je ne suis pas sur, ce serai à vérifier.
    2 n'est pas égal à 3, même pour de grandes valeurs de 2 ou de petites valeurs de 3

  8. #8
    Membre habitué Avatar de b Oo
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 179
    Points : 185
    Points
    185
    Par défaut
    Citation Envoyé par narkhor
    en disant "que pa[0] soit valide et que a[0] soit valide aussi" je suppose que tu veux dire qu'il devrai avoir le même effet.

    si c'est le cas, je ne pense pas que se soit une bonne idée.
    pa est un A*, quand tu utilise l'opérateur [i] dessus, je m'imagine plutot que tu essai d'accéder au ième élement, d'un tableau de A; tableau nommée pa.
    en voulant changé cet opérateur, le code risque d'être difficilement compréhensible par une autre personne.
    Salut narkhor,
    ce que je voulais faire c'était un peu comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int tab[10];
    int * ptab = tab;
    cout << tab[1] << endl;
    cout << ptab[1] << endl;
    sauf que je voulais le faire avec ma classe A.

    Je croyais que le fait de définir l'opérateur[] me permettrait de faire A[] avec A qui aurait pu être un pointeur ou non.
    Cela n'est pas conseillé comme tu l'as dit.

    En fait je considérais mon A comme un tableau (donc un pointeur) et je ne voyais pas pourquoi mon code ne fonctionnait pas et aussi car this (le paramètre "caché" qui est passé dans operator[](int i)) est un pointeur.
    Et dans ma tête je croyais que lorsque je faisais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    A a;
    A * pa = &a;
    cout << pa[i]; // ne fais pas ce que j'attends
    cout << a[i];
    cela faisait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    cout << pa->operator[](i); // fait ce que j'attends
    cout << a.operator[](i);
    donc pour moi il n'y avait pas d'erreur dans mon code, mais ceci n'est pas possible car les deux écritures ne sont pas gérées de la même manière.

    Le premier code me donnera l'adresse de a si i =0 et ne fonctionnera pas sinon.

    Le deuxième code devrait fonctionner pour ce que j'attends (ie me retourner l'élément contenu à la position i dans a).

    J'apporte une précision sur ce que tu as dit narkhor qui n'est pas du tout équivalent :
    Citation Envoyé par narkhor
    deux choses que je croit vrai mais qu'il faudrai vérifier:
    - (*pa)[i] est équivalent à *pa[i]
    (*pa)[i] est équivalent à : a[i] avec pa qui pointe sur a
    *pa[i]
    est équivalent à : *(pa+i) donc si i=0, (pa+i) est l'adresse de a ie *(pa+i) est équivalent à a, sinon cela fait quelque chose d'indéterminé.
    b Oo

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

Discussions similaires

  1. [OL-2003] Problème avec compte Gmail en IMAP: opération échouée
    Par midiweb dans le forum Outlook
    Réponses: 0
    Dernier message: 20/01/2012, 21h38
  2. Réponses: 3
    Dernier message: 15/09/2008, 14h24
  3. Problème avec opération sur les double
    Par luimême dans le forum C#
    Réponses: 2
    Dernier message: 17/04/2008, 10h19
  4. Réponses: 19
    Dernier message: 21/11/2006, 11h57
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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