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 :

Surcharges d'opérateur avec 2 pointeurs en argument


Sujet :

C++

  1. #1
    Membre éclairé Avatar de Ekinoks
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2003
    Messages
    687
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2003
    Messages : 687
    Par défaut Surcharges d'opérateur avec 2 pointeurs en argument
    Salut !

    J'aimerais savoir si vous connaissez un moyen de "tricher" pour arriver a faire des surcharges d'opérateur qui prenne en argument des pointeur d'objet ?

    Si on essaye de faire ca comme ca :
    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
     
    class A
    {
    	int val;
     
    	public :
    		A(int arg) : val(arg){}
     
    		A *operator + (A *x, A *y) {
    			return new A(x->val + y->val);
    		}
    };
    int main()
    {
    	A *a = new A(4);
    	A *b = new A(2);
    	A *c;
     
    	c = a+b;
     
    	return 0;
    }
    Ca ne compile pas et on reçoi le message d'erreur :
    erreur: «A* A::operator+(A*, A*)» must take either zero or one argument
    Apparemment il faut qu'au moins un des argument soit un type utilisateur


    Connaissez vous une manière de passer outre cette limitation ?

    Merci pour votre aide.

  2. #2
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Salut,

    pour moi le seul moyen c'est d'utiliser une classe qui fait exactement la même chose qu'un pointeur...

    (inspiré de la STL)
    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
    #include <iostream>
     
    using namespace std;
     
    template <class T>
    struct ptr
    {
        T *data;
     
        ptr() : data(NULL)
          { ; }
     
        ptr(T* item) : data(item)
          { ; }
     
        operator T*() const
          { return data; }
     
        const T& operator * () const
          { return *data; }
     
        T& operator * ()
          { return *data; }
     
        T* operator->() const
          { return &(operator*()); }
     
        T* operator->()
          { return &(operator*()); }
     
        ptr<T> operator+(const T &item) const
          { return data + item.data; }
     
        const ptr<T> & operator=(const T &item)
          { data = item.data; return (*this); }
    };
     
    class A
    {
    	public :
            int val;
    		A(int arg) : val(arg){}
    };
     
    ptr<A> operator + (ptr<A> x, ptr<A> y) {
        return new A(x->val + y->val);
    }
     
     
    int main()
    {
    	ptr<A> a = new A(4);
    	ptr<A> b = new A(2);
    	ptr<A> c;
     
    	c = a+b;
     
    	cout << c->val << endl;
     
    	return 0;
    }
    ici la classe ptr<A> correspond à un A*.

    Tu peux effectuer les conversions (elles sont en plus implicites) dans les deux sens:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ptr<A> a;
    A *b;
     
    //...
     
    a = b;
     
    /* ou */
     
    b = a;
    Navré je vois pas d'autre solution

  3. #3
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Les operateurs doivent aovoir au moins un argument qui est un typedefini par l'utilisateur, donc ce que tu veut n'est possible qu'en encapsulant le pointeur.

    Note que les regles de surcharge ne permettent pas d'utiliser les conversions implicites pour contourner la regle, meme dans les cas ou l'operation n'est pas valide comme l'addition de deux pointeurs.

    Note aussi que ce que tu tentes de faire, c'est declarer un operateur a trois arguments.

    Note enfin que j'ai des grosses reserves sur l'idee meme de combiner la surcharge d'operateurs comme l'addition qui ont une forte connotation de semantique de valeur et le fait de reourner un pointeur vers de la memoire nouvellement allouee. Des que qqun fairait a + b + c tu as une fuite de memoire.

  4. #4
    Membre éclairé Avatar de Ekinoks
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2003
    Messages
    687
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2003
    Messages : 687
    Par défaut
    Merci pour vos réponses =)

    coyotte507> excellant comme solution ! en redéfinissant également le new pour qu'il renvoie un ptr<A> a la place d'un *A, ça devrais faire l'affaire =)
    Merci

    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Des que qqun fairait a + b + c tu as une fuite de memoire.
    A vrai dire cela ne créeras pas mémoire nouvellement allouée, mais renverra un pointeur de A.

    "a + b + c" créera une sorte de liste chainé. dont la tête est a. (exactement une liste d'instruction a réaliser simultanément "a", "b" et "c").

    a utiliser de cette maniérè :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ptr<Animation> total = new Translation(..) + new Rotation(..) + new Translation(..)
    penses tu qu'il vaudrais mieux que je ne passe pas par des pointeurs ? ou que ma technique est mauvaise ? :^/

  5. #5
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Ca ne me plait pas a plusieurs niveaux.
    - au niveau conception, j'ai l'impression qu'il y a des choses qui ne sont pas claires dans ton esprit sur la difference entre entite et valeur mais c'est difficile a diagnostiquer quoi et encore plus difficle de proposer une alternative parce que tu n'as fait que des allusions a ton probleme
    - au niveau implementation, l'utilisateur de la surcharge me semble un abus clair

  6. #6
    Membre éclairé Avatar de Ekinoks
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2003
    Messages
    687
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2003
    Messages : 687
    Par défaut
    Merci pour ta réponse Jean-Marc.Bourguet

    Ok, je vais essayer d'expliquer plus en détail ^^

    En fait, je suis en train de me créer une librairie pour pouvoir créer rapidement et simplement des GUI (avec dessin).

    Pour le moment le code ressemble a ca sur un exemple simple :
    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
     
    int main (int argc, char *argv[])
    {
        // Initialisation
        init(&argc, &argv);
     
        // Création de la fenétre (800x600)
        Fenetre * fenetre = new Fenetre("Titre", 800, 600);
     
        // Création d'une aire de dessin
        Dessin * dessin = new Dessin();
     
        // On insert la zone de dessin dans la fenêtre
        fenetre->add(dessin);
     
        // Dessiner un cecle
        dessin->dessiner(new Cercle(100, 100, 10), true);  // true signifie que si on nettoie le dessin, il faut faire un delete de l'objet
     
        // GO !!!
        fenetre->go();
     
        return 0;
    }
    Jusqu'à présent je travaille à chaque foi avec des pointeur d'objet.
    Par exemple : on peu ajouter dans la fenêtre un dessin en donnant en paramétré, un pointeur vers objet "Dessin" dans la méthode "add" de la class Fenetre.

    Il m'a semblait qu'il été plus judicieux de récupérer des pointeurs pour ne pas avoir à faire de recopie d'objet.


    Maintenant j'aimerais pouvoir ajouter des animations à mes objets dessinable.
    J'ai donc fait une première version comme ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Dessinable *animation = new Translation( new Cercle(100, 100, 10), 100, 0, 0.2 );  // on creer une animation d'un cercle qui va se déplacer de 100 pixel sur l'axe X à la vitesse de 0.2
     
    Dessinable * animation2 = new Rotation( animation, 90, 0.2); // on creer une animation de l'objet "animation" qui va tourner sur lui même de 90° à la vitesse de 0.2
     
    dessin->dessiner(animation2);  // au total ca va créé un cercle qui va tourner sur lui même de 90° tout en effectuant une translation de 100pixele sur l'axe X
    Le problème est que si on veux ecrire ca en une seul ligne, cela devient compliquer et illisible...
    j'ai donc pensé a simplifier l'écriture de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    dessin->dessiner( new Cercle(100, 100, 10) + new Translation(100, 0, 0.2) + new Translation(90, 0.2) );
    Voila donc pour quoi je me posais la question de savoir comment faire pour surcharger un opérateur avec 2 pointeurs en argument ^^

    Pense tu que je ne devrais pas faire comme ça ?


    Merci.

  7. #7
    Membre émérite

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Par défaut
    C'est quand même bizarre d'utiliser l'opérateur + ici car la sémantique et assez éloignée d'une addition. L'opérateur * à la rigueur (composition).

    En tout cas tu peux toujours remplacer un opérateur par une simple fonction membre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new Cercle(100, 100, 10)->Add(new Translation(100, 0, 0.2))->Add(new Rotation(90, 0.2))
    Mais peut-être que le plus simple reste d'écrire tout simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new Rotation(new Translation(new Cercle(100, 100, 10), 100, 0, 0.2), 90, 0.2)
    Ou mieux en utilisant une matrice de transformation, il ne devrait même pas y avoir besoin d'une hiérarchie de classes.

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Sylvain,

    Comme ses transformations sont des mouvements, j'ai l'impression qu'il se sert
    de ses classes pour stocker le point courant. Ce doit etre pour cela qu'elles
    doivent etre des entites.

    Globalement, sa conception (ou du moins celle que je devine) ne me plait pas,
    mais j'ai pas le temps de reflechir au probleme pour proposer mieux. A priori
    je separerais la valeur descrivant la transformation et l'entite maintenant l'etat
    courant.

    A+

    --
    Jean-Marc

  9. #9
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Les operateurs doivent aovoir au moins un argument qui est un typedefini par l'utilisateur
    Je me demandais récemment si les types définis dans la SL entraient ou pas dans cette catégorie.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  10. #10
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je me demandais récemment si les types définis dans la SL entraient ou pas dans cette catégorie.
    Ils y entrent. Rien ne t'empeche de definir

    std::ostream& operator<<(std::ostream&, std::vector<int>)

    dans que ce n'est pas dans le namespace std. Attention cependant a ce qui peut n'etre qu'n typedef (certains iterateurs sont dans certaines implementation de la Sl que des pointeurs).

Discussions similaires

  1. surcharge d'opérateur avec classes différentes
    Par weird73 dans le forum C++
    Réponses: 7
    Dernier message: 23/01/2013, 18h03
  2. Problème de surcharge d'opérateur flux avec pointeur
    Par eleve_prog dans le forum Débuter
    Réponses: 4
    Dernier message: 18/04/2011, 18h41
  3. surcharge d'opérateur avec parametre
    Par contremaitre dans le forum C++
    Réponses: 7
    Dernier message: 15/06/2010, 12h24
  4. appel d'une fonction avec pointeur comme argument
    Par airness86180 dans le forum Débuter
    Réponses: 1
    Dernier message: 06/03/2009, 13h34
  5. surcharge d'opérateur et pointeur
    Par cyril_sy dans le forum C++
    Réponses: 3
    Dernier message: 24/08/2007, 17h19

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