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 :

Ma surcharge de l'opérateur << ne fonctionne pas, sur ma classe vecteur.


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut Ma surcharge de l'opérateur << ne fonctionne pas, sur ma classe vecteur.
    Bonsoir,

    Je suis en train de programmer une classe vecteur qui est censé représenter des vecteurs de dimensions quelconque.
    Et j'aimerais bien surcharger pas mal d'opérateurs sur cette classe mais là j'ai un peu de mal.

    Je vous met la classe dans l'état actuel:

    Vecteur.h
    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
    #ifndef VECTEUR
    #define VECTEUR
     
    #include <vector>
     
     
     
    /*!
     * \class Vecteur
     * \brief La classe Vecteur représente un vecteur dans un espace de dimension quelconque.
     */
    class Vecteur{
     
        public :
        /*!
         * \brief Constructeur de la classe Vecteur.
         *
         *  Construit un vecteur de dimension nombreComposantes qui valent toutes composante.
         *
         *  \param nombreComposantes : dimension du vecteur = nombre de composantes du vecteur. Doit être sctricement positif.
         *  \param composante : valeur des composantes du vecteur.
         */
        Vecteur(unsigned int nombreComposantes, long double composante=0 );
     
     
        /*!
         * \return la dimension du vecteur.
         */
        unsigned int size() const;
     
        /*!
         *  \brief Surcharge de l'opérateur []
         *
         *  \param numeroComposante : numéro de la composante du vecteur à affecter. Va de 0 jusqu'à dimension du vecteur -1.
         *  \return Une référence sur la composante du vecteur
         */
        long double operator[](const unsigned int numeroComposante) const;
        long double& operator[](const unsigned int numeroComposante);
     
     
     
        private:
            std::vector<long double> m_vecteur; //!<Tableau dynamique contenant l'ensemble des composantes du vecteur.
     
    };
     
    #endif
    Vecteur.cpp
    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
    #include "Vecteur.h"
    #include <cmath>
    #include <iostream>
     
     
     
    Vecteur::Vecteur(unsigned int nombreComposantes, long double composante)
    {
        if(nombreComposantes >0)
            m_vecteur.assign(nombreComposantes, composante);
    }
     
    unsigned int Vecteur::size() const
    {
        return m_vecteur.size();
    }
     
    long double Vecteur::operator[] (const unsigned int numeroComposante) const
    	{
    	    return m_vecteur[numeroComposante];
    	}
     
    long double& Vecteur::operator[] (const unsigned int numeroComposante)
    	{
    	    return m_vecteur[numeroComposante];
    	}
     
    ostream &operator<<( ostream &out, const Vecteur &vecteur )
    {
        for(unsigned int i=0; i<vecteur.size();i++)
            out << vecteur[i] << " " ;
        return out;
    }
    Donc si j'ai bien compris pour surcharger "<<" il ne faut pas la mettre dans le classe. C'est bien ce que j'ai fait.
    Mais à la ligne de la définition de la méthode j'ai l'erreur: " expected constructor, destructor, or type conversion before '&' token "

    Qu'est-ce qui ne vas pas ?

    Merci.

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Cette entrée de la FAQ traite du sujet.

    MAT.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Salut,

    Cette entrée de la FAQ traite du sujet.

    MAT.
    Oui j'ai fait exactement comme dans la FAQ, et je ne comprend pas pourquoi ça ne fonctionne pas.

    Sauf que dans la FAQ la fonction est dans le .h et qu'ici je l'ai mis dans le .cpp, mais j'ai testé les deux et j'ai la même erreur.

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Il manque std:: devant stream dans ta version.
    Mais il faut aussi la déclaration (avec le friend pour pouvoir accéder à m_vecteur) dans le .h

    En fait la FAQ mélange à la fois la déclaration et l'implémentation, c'est vrai que c'est sans doute déroutant quand on n'a pas l'habitude...

    MAT.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Il manque std:: devant stream dans ta version.
    J'avais également testé de mettre le std::
    Toujours une erreur mais ce n'est pas la même " declaration of 'operator<<' as non-function"

    Citation Envoyé par Mat007 Voir le message
    Mais il faut aussi la déclaration (avec le friend pour pouvoir accéder à m_vecteur) dans le .h
    Oui j'avais aussi essayé de mettre la déclaration dans le .h (j'ai testé dans la class et en dehors) et toujours l'erreur.

    Par contre j'ai pas besoin de mettre la fonction en friend puisque si tu regardes bien j'ai surchargé l'opérateur []

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par Cpowa Voir le message
    Par contre j'ai pas besoin de mettre la fonction en friend puisque si tu regardes bien j'ai surchargé l'opérateur []
    Au temps pour moi !

    Si tu veux pouvoir utiliser l'opérateur ailleurs il faut quelque chose dans le .h :
    . soit l'implémentation de l'opérateur en dehors de la classe avec un inline devant et un include <iostream> en haut
    . soit la déclaration en dehors de la classe, avec un include <iosfwd> en haut, et l'implémentation dans le .cpp

    Quel est ton compilateur ?

    MAT.
    ps : re-colle le code avec la correction du std:: et une des deux solutions ci-dessus au choix pour voir ?

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut
    Citation Envoyé par Mat007 Voir le message

    Si tu veux pouvoir utiliser l'opérateur ailleurs il faut quelque chose dans le .h :
    . soit l'implémentation de l'opérateur en dehors de la classe avec un inline devant et un include <iostream> en haut
    . soit la déclaration en dehors de la classe, avec un include <iosfwd> en haut, et l'implémentation dans le .cpp
    Tu parles de l'opérateur [] ou << ?

    Citation Envoyé par Mat007 Voir le message
    Quel est ton compilateur ?
    mingw32, j'ai aussi g++ si besoin.

  8. #8
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par Cpowa Voir le message
    Tu parles de l'opérateur [] ou << ?
    De << !

    MAT.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut
    Aucune des deux méthodes ne fonctionne, j'ai toujours la même erreur.

    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
     
    #ifndef VECTEUR
    #define VECTEUR
     
    #include <vector>
    #include <iostream>
    #include <iosfwd>
     
    /*!
     * \class Vecteur
     * \brief La classe Vecteur représente un vecteur dans un espace de dimension quelconque.
     */
    class Vecteur{
     
        public :
        /*!
         * \brief Constructeur de la classe Vecteur.
         *
         *  Construit un vecteur de dimension nombreComposantes qui valent toutes composante.
         *
         *  \param nombreComposantes : dimension du vecteur = nombre de composantes du vecteur. Doit être sctricement positif.
         *  \param composante : valeur des composantes du vecteur.
         */
        Vecteur(unsigned int nombreComposantes, long double composante=0 );
     
     
        /*!
         * \return la dimension du vecteur.
         */
        unsigned int size() const;
     
        /*!
         *  \brief Surcharge de l'opérateur []
         *
         *  \param numeroComposante : numéro de la composante du vecteur à affecter. Va de 0 jusqu'à dimension du vecteur -1.
         *  \return Une référence sur la composante du vecteur
         */
        long double operator[](const unsigned int numeroComposante) const;
        long double& operator[](const unsigned int numeroComposante);
     
     
    };
     
     
    inline std::ostream &operator<<( ostream &out, const Vecteur &vecteur );
     
    #endif
    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
    /*!
    * \file Vecteur.cpp
    * \brief Fichier d'implémentation de la classe Vecteur
    */
     
     
     
     
    #include "Vecteur.h"
    #include <cmath>
     
     
     
     
    Vecteur::Vecteur(unsigned int nombreComposantes, long double composante)
    {
        if(nombreComposantes >0)
            m_vecteur.assign(nombreComposantes, composante);
    }
     
    unsigned int Vecteur::size() const
    {
        return m_vecteur.size();
    }
     
    long double Vecteur::operator[] (const unsigned int numeroComposante) const
    	{
    	    return m_vecteur[numeroComposante];
    	}
     
    long double& Vecteur::operator[] (const unsigned int numeroComposante)
    	{
    	    return m_vecteur[numeroComposante];
    	}
     
    inline std::ostream &operator<<( ostream &out, const Vecteur &vecteur )
    {
        for(unsigned int i=0; i<vecteur.size();i++)
            out << vecteur[i] << " " ;
        return out;
    }

  10. #10
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Il manque std:: devant l'autre ostream (le premier paramètre).

    Et inline c'est pour une implémentation qui est dans le .h
    Bon là ça fait au pire juste rien dans les deux cas donc à la limite c'est pas très grave.

    MAT.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Il manque std:: devant l'autre ostream (le premier paramètre).

    Et inline c'est pour une implémentation qui est dans le .h
    Bon là ça fait au pire juste rien dans les deux cas donc à la limite c'est pas très grave.

    MAT.
    Ah oui pardon, je les oubliait tout le temps
    Du coup même pas besoin de d'inclure <iosfwd>

    On aurait encore pu continuer comme-ça longtemps

    Merci.

    Je ne met pas ce sujet en résolu au cas ou j'ai des problèmes à surcharger les autres opérateurs.
    Je le ferais quand j'aurais terminé ma classe.

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut
    J'ai un problème pour l'opérateur >>.

    j'ai une méthode qui permet de renseigner les composantes d'un vecteur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void Vecteur::entrerCoordonnees()
    {
        for(unsigned int i=0; i<m_vecteur.size();i++)
            std::cin >>  m_vecteur[i];
    }
    Et j'aimerais remplacer celle-ci par la surcharge de l'opérateur >>.

    J'ai donc fait ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    std::istream &operator>>( std::istream &fluxEntrant, const Vecteur &vecteur )
    {
        std::cout << "Entrez les " << vecteur.size() << " coordonnees : ";
        for(unsigned int i=0; i<vecteur.size();i++)
            fluxEntrant >> vecteur[i];
        return fluxEntrant;
    }
    Mais ça ne fait pas du tout ce que je veux.
    Le programme n'attend même pas que j'entre un nombre.

    Comment faire ?

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut
    Encore un autre soucis, j'ai surchargé l'opérateur -:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Vecteur operator-(const Vecteur &v1, const Vecteur &v2)
    {
        Vecteur difference(v1.size());
     
        if(v1.size()== v2.size())
        {
            for(unsigned int i=0; i<v1.size();i++)
                difference[i]=v1[i]-v2[i];
        }
     
        return difference;
    }
    Du coup je peux écrire v1-v2;
    Mais j'ai toujours pas le droit d'écrire -v1;
    Comment je dois faire pour permettre cette possibilité ?

    merci.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Il faut déclarer l'operateur unaire - :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Vecteur operator-(Vecteur const& v);
    Au passage, on implémente généralement les operateurs +,-,etc... à partir de += et -= :
    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 Vecteur
    {
        //....
        Vecteur& operator+=(Vecteur const& v);
        Vecteur& operator-=(Vecteur const& v);
    };
     
    Vecteur operator-(Vecteur const& v1, Vecteur const& v2)
    {
         Vecteur vResultat(v1);
         vResultat -= v2;
         return vResultat;
    }
     
    // meme chose pour l'operateur +

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut
    Citation Envoyé par Joe Dralliam Voir le message
    Il faut déclarer l'operateur unaire - :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Vecteur operator-(Vecteur const& v);
    Ok, du coup j'ai préféré l'implémenter comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Vecteur& Vecteur::operator-()
    {
        for(unsigned int i=0; i<m_vecteur.size();i++)
            m_vecteur[i]=-m_vecteur[i];
     
            return *this;
     
    }
    Comme ça c'est une méthode de ma classe.

    Mais y a un problème.

    Si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Vecteur v1(2), v2(2);
     
    v2=-v1;
    cout << v2;   //Ca ça fonctionne
     
    cout << -v1; // Ca par contre ça m'affiche v1 et pas -v1 pourquoi ?

    Citation Envoyé par Joe Dralliam Voir le message
    Au passage, on implémente généralement les operateurs +,-,etc... à partir de += et -= :
    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 Vecteur
    {
        //....
        Vecteur& operator+=(Vecteur const& v);
        Vecteur& operator-=(Vecteur const& v);
    };
     
    Vecteur operator-(Vecteur const& v1, Vecteur const& v2)
    {
         Vecteur vResultat(v1);
         vResultat -= v2;
         return vResultat;
    }
     
    // meme chose pour l'operateur +
    Ouais j'ai vu ça mais vu que j'utilise quasi jamais les -=, += etc je trouve que ça surchargerait ma classe inutilement.


    Sinon pas d'idée pour la surcharge de ">>" ?

  16. #16
    Invité
    Invité(e)
    Par défaut
    L'operateur - unaire ne devrait pas changer l'instance sur lequel il est appliqué. Sa signature devrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Vecteur Vecteur::operateur-() const;
    C'est assez logique; si tu prend les types primaires (int, double, char, etc..) tu ne t'attends pas à ce comportement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int entier = 5;
    -entier; //entier vaut toujours 5
    std::cout << entier << std::endl;
    // par contrer le résultat est son opposé :
    std::cout << -entier << std::endl;
    Edit : Peux tu donner quelques information sur ton utilisation de l'operateur >> (le code ne me semble pas buggué...)

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut
    Citation Envoyé par Joe Dralliam Voir le message
    L'operateur - unaire ne devrait pas changer l'instance sur lequel il est appliqué. Sa signature devrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Vecteur Vecteur::operateur-() const;
    C'est assez logique; si tu prend les types primaires (int, double, char, etc..) tu ne t'attends pas à ce comportement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int entier = 5;
    -entier; //entier vaut toujours 5
    std::cout << entier << std::endl;
    // par contrer le résultat est son opposé :
    std::cout << -entier << std::endl;
    Ok merci, j'ai compris et ça fonctionne.

    Citation Envoyé par Joe Dralliam Voir le message
    Edit : Peux tu donner quelques information sur ton utilisation de l'operateur >> (le code ne me semble pas buggué...)
    Ben par exemple je fais (dans le main)
    Et ça m'affiche "Entrez les 2 coordonnees : Entrez les 0 coordonnees : Entrez les 0 coordonnees :"

  18. #18
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par Cpowa Voir le message
    Mais ça ne fait pas du tout ce que je veux.
    Retire le const devant Vecteur& !
    Je suis étonné que ça compile (sans warning).

    Et puis comme le vecteur est vide initialement, vecteur.size() renvoie 0, et donc ça ne peut pas fonctionner. :p

    MAT.

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Retire le const devant Vecteur& !
    Je suis étonné que ça compile (sans warning).

    Et puis comme le vecteur est vide initialement, vecteur.size() renvoie 0, et donc ça ne peut pas fonctionner. :p

    MAT.
    Ah oui je suis bête, merci.

    Ma classe est donc terminée j'ai pas eu de mal à surcharger les autres opérateurs.
    Toujours un plaisir de se faire aider sur developpez

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

Discussions similaires

  1. Surcharge de l'opérateur new
    Par :Bronsky: dans le forum C++
    Réponses: 17
    Dernier message: 27/10/2010, 21h33
  2. Réponses: 8
    Dernier message: 29/08/2006, 00h56
  3. [C#] Surcharge de l'opérateur ==
    Par LE NEINDRE dans le forum Windows Forms
    Réponses: 3
    Dernier message: 18/07/2006, 16h19
  4. Réponses: 6
    Dernier message: 12/07/2006, 15h34
  5. Réponses: 15
    Dernier message: 25/01/2005, 16h51

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