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 :

[Programmation] Opérateur parenthèse () classe mère-fille


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 3
    Points : 1
    Points
    1
    Par défaut [Programmation] Opérateur parenthèse () classe mère-fille
    Bonjour à tous.

    Ma question est simple:
    je désire créer un opérateur () (ex: operator() (int i, int j) )dans une classe fille, sachant que la classe mère possède elle même cet opérateur. Je connais l'utilisation du mot
    clé virtual, mais j'aurais voulu savoir s'il était possible de renvoyer
    un type différent que ce soit dans la classe mère ou la classe fille?
    par example double & pour la mère et double pour la fille.

    Si oui pourriez vous donner un exemple.

    Je vous remercie d'avance.

    http://math.linux.free.fr/

    Cordialement.

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Non, c'est impossible. Mais pourquoi vouloir renvoyer un double& dans la classe mère et un double pour la classe fille : Tu peux expliquer un peu le contexte ?

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Salut Loulou24,
    je m'attendais à ta réponse vu le message d'erreur qui m'était renvoyé !
    Le contexte est le suivant:

    je possede une classe mère matrice dans laquelle l'opérateur ()
    permet non seulement d'accéder aux éléments mais aussi de les modifier
    d'ou le passage par référence (double &)

    J'appelle matrice creuse une matrice dans laquelle il y beaucoup de zéros
    et ou on stocke seulement les éléments non nuls (un indice (i,j) et une valeur value)

    J'ai une classe fille matrice_creuse dans laquelle je désire faire un opérateur()
    mais qui ne modifie pas mon tableau creux d'ou le double sans référence.

    L'idée est de pouvoir accéder à des éléments de matrice_creuse sans les modifier , pour la modification j'utilise une fonction du type M.set(i,j,value)

    Pourquoi ce choix?
    J'aurais voulu faire un opérateur () avec comme sortie double & mais des
    problèmes sont intervenus:
    Soit M une matrice_creuse


    1) si je demande M(1,2)
    j'ai deux alternatives soit l'élément (1,2) existe et auquel cas il me renvoi sa valeur, soit il n'existe pas et à ce moment là l'élément (1,2) est crée et me
    renvoie 0
    2)Ce n'est pas ce que je veux, puisque si l'élément n'existe pas , je voudrais
    qu'il me renvoit zéro sans pour autant créer l'élément (1,2).


    Ma question est alors la suivante:
    est il possible de créer un opérateur () tel que celui ci sache distinguer
    le fait que je demande une valeur M(1,2) (sans modif) et le fait que je veuille modifier
    une valeur M(1,2)=3.14 ?

    J'ai essayé ce genre de chose
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    double& matrix_creuse::operator() (int i,int j)
    double matrix_creuse::operator() (int i,int j)const
    mais cela ne fonctionne pas.

    Merci d'avance.

    Cordialement.
    http://math.linux.free.fr

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Août 2003
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 247
    Points : 276
    Points
    276
    Par défaut
    Avant tout, matrice_creuse doit-elle dérivée de matrice ? Je pense que c'est la dernière chose à faire. Si tu tient à avoir un comportement polymorphique, tu peut faire dérivé les deux classes d'une classe abstraite. L'idée ne me parait pas très bonne.

    Je me tournerais plutôt vers un design STL-like : une matrice est un objet qui se comporte comme une matrice. Tu définit tes deux classes séparément. Ensuite, tu peux implémenter des itérateurs.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Août 2004
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 35
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par nsoualem
    1) si je demande M(1,2)
    Code:
    cout<<M(1,2)

    j'ai deux alternatives soit l'élément (1,2) existe et auquel cas il me renvoi sa valeur, soit il n'existe pas et à ce moment là l'élément (1,2) est crée et me
    renvoie 0
    2)Ce n'est pas ce que je veux, puisque si l'élément n'existe pas , je voudrais
    qu'il me renvoit zéro sans pour autant créer l'élément (1,2).
    je propose cette solution pas très élégante mè ki marche
    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 matrix_creuse {
    public :
    double& operator() (int i,int j);
    private :
    doubele Zero;
    }
     
    double& matrix_creuse::operator() (int i,int j)  {
      // if(valeur_matrice<>0) return valeur
      //else {
        Zero = 0.0;
        return Zero;
      //}
     
    }

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Août 2003
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 247
    Points : 276
    Points
    276
    Par défaut
    Citation Envoyé par Rely
    Citation Envoyé par nsoualem
    1) si je demande M(1,2)
    Code:
    cout<<M(1,2)

    j'ai deux alternatives soit l'élément (1,2) existe et auquel cas il me renvoi sa valeur, soit il n'existe pas et à ce moment là l'élément (1,2) est crée et me
    renvoie 0
    2)Ce n'est pas ce que je veux, puisque si l'élément n'existe pas , je voudrais
    qu'il me renvoit zéro sans pour autant créer l'élément (1,2).
    je propose cette solution pas très élégante mè ki marche
    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 matrix_creuse {
    public :
    double& operator() (int i,int j);
    private :
    doubele Zero;
    }
     
    double& matrix_creuse::operator() (int i,int j)  {
      // if(valeur_matrice<>0) return valeur
      //else {
        Zero = 0.0;
        return Zero;
      //}
     
    }

    (Pas de SMS, SVP.)
    (L'opérateur <> n'existe pas en C++.)

    Cette solution est excécrable, car on peut écrire M(i, j) = a.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 15
    Points : 18
    Points
    18
    Par défaut
    D'apres ce que j'ai compris,

    tu as une classe Matrice, dont l'operateur () est surchargé et retourne un double &, et tu souhaite avoir une classe Matrice_creuse, dont ce meme operateur retourne un double.

    Je pense que, meme si il y aurait (peut etre) des méthodes tres bourrines pour arriver à un truc proche, ce n'est pas une bonne idee, je m'explique :

    Je suppose que si tu veux faire un pseudo polymorphisme, c'est que tu compte t'en servir. Imaginons un cas de figure tres simple : tu fait un tableau de matrices, dont certaines sont des matrices_creuses. Tu utilise l'operateur () sur les membres de ce tableau, l'effet ne sera absolument pas le meme selon quel type de matrice tu as.

    Je pense qu'il vaut mieux faire 2 classes separees, à moins que tu aie reellement besoin de cela, mais je pense que, meme si pour toi c'est utile, en refléchissant mieux au probleme, tu trouvera une solution plus "propre".

  8. #8
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Ok alors oublions le fait que cette fonction dérive de matrice.

    comment faire pour créer un tel opérateur() qui satisfasse les
    conditions suivantes:

    1) si je demande un couple (i,j) non existant
    alors il me renvoie zéro sans créer le couple
    2)si je demande un couple existant il me renvoie sa valeur
    3)si je dis M(k,l)=3.14, il crée l'indice k,l s'il n'existe pas ou remplis la valeur avec 3.14 si le couple existe


    Est ce possible?

  9. #9
    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
    En retournant des proxys ?
    Sinon, regardes comment ont procédé Blitz++ et compagnie.

    (Autrement, casser le LSP, c'est mal ; google -> LSP, liskov, Robert C Martin, carrés qui ne sont pas des rectangles, ...)
    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...

  10. #10
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Je suis d'accord qu' il est difficile de ne pas faire une classe indépendante pour ta matrice creuse.
    Comme ton problème est rigolo, j'ai réfléchi un peu dessus et comme il est dommage d'abandonner la syntaxe habituelle j'ai pensé plutôt surcharger l'opérateur [] . La grosse difficulté est évidemment de toute façon de supprimer automatiquement les éléments affectés de la valeur 0.
    Mon but était de pouvoir écrire des choses du genre
    Tab[1][2] = 5.0
    Tab[1][2] = Tab[2][3] +10
    Tab[1][2] = Tab[2][3] = 10
    double x = Tab[5][6]
    et, le plus difficile, que l'écriture
    Tab[1][2] =0
    supprime cet élément si il existe.
    Je suis arrivé à une solution que je t'enverrais demain (je suis distrait et j'ai laissé le souce ailleurs )
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  11. #11
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    J'ai deux versions à te proposer . la première travaille en surchargeant [] et la seconde, un peu plus simple en surchargeant (). Sinon leur principe est le même.
    La plus simple avec ():
    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
    class Tab2D
    {
     typedef std::map<unsigned long,double,std::less<unsigned long> > Map;
     //-----------
     class Data
      {
        public :
        double data;
        Map * m;
        unsigned long key;
        operator double (){ return data;};
        double  operator =(double val)
          {
            if(val !=0.0)(*m)[key] = val;
              else (*m).erase(key);
            return  val;
          };
       Data (Map * M,unsigned long k, double val):m(M),key(k),data(val){};
      };
     //-----------
     Map tab;
     public:
      Data  operator ()(unsigned long ligne,unsigned long colonne)
        {
         unsigned long key = ligne*65536+colonne;
         if(tab.count(key)==1) return Data(&tab,key,tab[key]);
         return Data(&tab,key,0.0);
        };
      int Count() { return tab.size(); };
      void Clear() { tab.clear();};
    };
    La construction de la clé suppose des unsigned long de 32 bits (au moins) et permet d'avoir des matrices creuses de dimensions maximum de 65536x65536, c'est à dire des indices variant de 0 à 65535.
    Le code est à "deux étages", l'un qui surcharge l'opérateur () et construit un objet temporaire type Data, l'autre le type Data se charge du transtypage en double et des opérateurs d'affectation. Je l'ai testé sur ce code :
    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
    //---------------------------------------------------------------------
    void main()
    {
      Tab2D Tab;
     int i;
     double f ;
     i = Tab.Count();           // i = 0
     Tab(1,2) = 3;             //    [1][2](3)
      i = Tab.Count();          // i = 1
     Tab(2,3) = 5;             //    [1][2](3)  [2][3](5)
      f = Tab(1,2);            // f = 3
      i = Tab.Count();          // i = 2
      Tab(1,2) = 7.4;          //    [1][2](7.4)  [2][3](5)
      i = Tab.Count();          // i = 2
      f = Tab(1,2);            // f = 7.4
      f = Tab(2,3) ;           // f = 5
      Tab(2,3) = 0;            //    [1][2](7.4)
      f= Tab(2,3) ;            // f = 0
      i = Tab.Count();          // i = 1
      Tab(4,5) = Tab(1,2)+5;  //    [1][2](7.4)  [4][5](12.4)
      i = Tab.Count();          // i = 2
      f = Tab(4,5) ;           // f = 12.4
      f = Tab(2,3) ;           // f = 0
      i = Tab.Count();          // i = 2
      Tab(2,3) = Tab(1,2)+Tab(4,5); // [1][2](7.4)  [4][5](12.4) [2][3](19.8)
      i = Tab.Count();          // i = 3
      f = Tab(1,2);            // f = 7.4
      f = Tab(2,3);            // f = 19.8
      f = Tab(7,8);            // f = 0
      Tab(7,8) = Tab(5,6) = 230+Tab(1,2) ;
                                // [1][2](7.4)  [4][5](12.4) [2][3](19.8)
                                // [7][8](237.4) [5][6](237.4)
      f = Tab(7,8);            // f = 237.4
      f = Tab(5,6);            // f = 237.4
      i = Tab.Count();          // i = 5
      Tab(1,2) = 0;            // [4][5](12.4) [2][3](19.8)
                                // [7][8](237.4) [5][6](237.4)
      i = Tab.Count();          // i = 4
      Tab.Clear();
      i = Tab.Count();          // i = 0
      for(int j =0; j<10;j++) Tab(j,j) = (j-5)*(j-5);
      i = Tab.Count();          // i = 9
      for(int j =0; j<10;j++)
       f = Tab(j,j);           // f = 25,16,9,4,1,0,1,4,9,...
      cout<< Tab(0,0)+1.2;       // "26.2"
      for(int j =0; j<10;j++)   Tab(j,j) = 0;
      i = Tab.Count();          // i = 0
    }
    C'est assez primitif, mais ça marche pas mal. Dis moi ce que tu en penses et si ça résoud ton problème ?
    Si tu es interressé par la version [][] , je peux te la communiquer. J'attends tes commentaires.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  12. #12
    Nouveau membre du Club
    Inscrit en
    Août 2004
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 35
    Points : 38
    Points
    38
    Par défaut
    diogène> j'ai testé ton code. bien que je ne l'ai pas fait rigoureusement je trouve qu'il reponds très bien aux préoccupations de nsoualem et qu'il est bien fait. maintenant il reste à nsoualem de donner son avis!

Discussions similaires

  1. [POO] Classe mère/fille surcharge
    Par shadeoner dans le forum Langage
    Réponses: 5
    Dernier message: 31/01/2008, 01h36
  2. Réponses: 1
    Dernier message: 13/09/2007, 13h25
  3. [POO]2 classes mère et une classe fille
    Par MysticKhal_0 dans le forum C++
    Réponses: 3
    Dernier message: 06/06/2006, 21h30
  4. Réponses: 6
    Dernier message: 01/05/2006, 19h05
  5. Ma classe fille n'hérite pas de sa classe mère
    Par Invité dans le forum Langage
    Réponses: 3
    Dernier message: 15/06/2005, 12h49

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