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

Langage C++ Discussion :

Surcharge de l'opérateur d'affectation


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2005
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 30
    Par défaut Surcharge de l'opérateur d'affectation
    Bonjour,

    J'ai lu la FAQ sur la surcharge d'opérateurs ici:

    http://cpp.developpez.com/faq/cpp/?p...GE_affectation

    Néanmoins, j'ai beaucoup de mal à définir la surcharge de mon opérateur d'affectation.

    Je travaille sur des matrices génériques, dans mon cas la ressource brute est:

    T * representation;

    et initialisée de la façon suivante:

    representation = new T[nLignes*nColonnes];

    ou nLignes et nColonnes sont deux entiers.

    J'ai su faire la surcharge du constructeur de copie de la façon suivante:

    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
     
    Matrice ( const Matrice<T> & other )
        {
            this->nLignes = other.nLignes;
            this->nColonnes = other.nColonnes;
            if (other.representation)
            {
                this->representation = new T(nLignes*nColonnes);
                for(int i = 0; i<nLignes; ++i)
                {
                    for(int j = 0; j<nColonnes; ++j)
                    {
                        this->representation[i*nColonnes + j] = other.representation[i*nColonnes + j]; //Si la matrice contient des pointeurs, on est morts !!!
                    }
                }
            }
            else
                this->representation = NULL;
        };
    J'ai donc fait mon destructeur et mon opérateur d'affectation de la façon suivante:

    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
     
        ~Matrice ()
        {
            cout << "destructeur de\n" ;
            this->afficher();
            delete this->representation;
        };
     
        Matrice<T>& operator=( const Matrice<T> & other)
        {
            Matrice temp(other);
            // Réaffectation : on prend les nouvelles données dans Temp, et on lui
            // donne les données à détruire en échange
            swap(temp.representation, this->representation);
     
            return *this;
     
        };
    Bon hier soir cela plantait (je faisais une somme de matrices) et j'ai fait des modifs aujourd'hui cela fonctionne, je ne sais pas trop d'ou venaient les problèmes car j'ai cherché dans plusieurs directions à la fois.

    Mes questions sont les suivantes:

    - relativement à la FAQ, mes trois méthodes - constructeur de copie, opérateur d'affectation, destructeur - sont elles correctes ?

    - Ceci devrait fonctionner dans que "representation" contient des objets et non des adresses: un entier, un float.... mais si un jour je me décide à coller des pointeurs d'entiers à l'intérieur je crois que je vais droit dans le mur.

    Y'a t'il une bonne façon pour implémenter ceci ? Par exemple representation pourrait ne travailler QUE avec des adresses, même si l'utilisateur passe des int ?

    Dans ce cas, comment dois-je gérer les constructeur de copie, destructeur, et opérateur d'affectation ?

    - Question subsidiaire: je suis dans l'incapacité de surcharger l'opérateur << sans faire appel à des accesseurs, representation étant privé et ceci malgré cette déclaration:

    friend ostream& operato<><<(ostream&, Matrice<T> & );

    ou

    friend ostream& operato<<<>(ostream&, Matrice<T> & );

    qui génèrent toutes deux des erreurs de compilation, que dois-je faire exactement ?

    Merci beaucoup !

  2. #2
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Ton opérateur d'affectation il copie pas toute les données :
    this->nLignes = other.nLignes;
    this->nColonnes = other.nColonnes;

    Et ton swap il a quel tête? (std ? fonction membre de la classe?)

    Sinon ton opérateur d'affectation pourrait avoir cette signature :

    Matrice<T>& operator=(Matrice<T> other)

    dans certain cas ça sera plus rapide que l'autre (et jamais plus lent).

    Pour l'op << montre le code entier.

  3. #3
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2006
    Messages : 37
    Par défaut
    Citation Envoyé par Zangdaarr Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Matrice ( const Matrice<T> & other )
        {
    // ...
           if (other.representation)
            {
                this->representation = new T(nLignes*nColonnes);
    
    // Ici tu crées un T initialisé avec le résultat de nbLignes*nColonnes ; ce que tu veux c'est 
    new T[nbLignes*nColonnes];
    Mes questions sont les suivantes:

    - relativement à la FAQ, mes trois méthodes - constructeur de copie, opérateur d'affectation, destructeur - sont elles correctes ?
    Je n'ai pas lu la FAQ :-) Je n'ai pas vu d'erreur.

    - Ceci devrait fonctionner dans que "representation" contient des objets et non des adresses: un entier, un float.... mais si un jour je me décide à coller des pointeurs d'entiers à l'intérieur je crois que je vais droit dans le mur.

    Y'a t'il une bonne façon pour implémenter ceci ?
    Tu te poses trop de questions. Tu as le même problème avec un std::vector<> et il est résolu avec des pointeurs « intelligents ».

    - Question subsidiaire: je suis dans l'incapacité de surcharger l'opérateur << sans faire appel à des accesseurs, representation étant privé et ceci malgré cette déclaration:

    friend ostream& operato<><<(ostream&, Matrice<T> & );

    ou

    friend ostream& operato<<<>(ostream&, Matrice<T> & );

    qui génèrent toutes deux des erreurs de compilation, que dois-je faire exactement ?
    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
    // Forward déclarations
    template< typename T >                                                                                                                                                               
    struct Matrix;
     
    template< typename T >                                                                                                                                                               
    std::ostream &                                                                                                                                                                       
    operator<<(std::ostream &, Matrix< T > const &);
     
    // La classe Matrix
    template< typename T >                                                                                                                                                               
    class Matrix {                                                                                                                                                                      
     
     // ...
     
     friend std::ostream &                                                                                                                                                               
     operator<< <>(std::ostream &, Matrix< T > const &);                                                                                                                    
     
    };

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Août 2005
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 30
    Par défaut
    Le constructeur de copie et la surcharge de = sont ainsi désormais (je n'ai pas encore utilisé copy):

    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
     
        /** -- CONSTRUCTEUR DE COPIE-- **/
        Matrice( const Matrice<T> & other )
        {
            this->nom = "copie de " + other.nom;
            this->nLignes = other.nLignes;
            this->nColonnes = other.nColonnes;
            if (other.representation)
            {
                this->representation = new T[nLignes*nColonnes];
                for(unsigned int i = 0; i<nLignes; ++i)
                {
                    for(unsigned int j = 0; j<nColonnes; ++j)
                    {
                        this->representation[i*nColonnes + j] = other.representation[i*nColonnes + j]; //Si la matrice contient des pointeurs, on est morts !!!
                    }
                }
            }
            else
                this->representation = NULL;
        };
     
        //matrice ( const UnString &  );//format “nl,nc,val1,val2,..,valnl*nc”
     
        /** -- DESTRUCTEUR -- **/
        ~Matrice ()
        {
            cout << "destructeur de " << this->nom << "\n"<< *this<< endl;
            delete[] this->representation;
        };
     
        Matrice<T>& operator=( const Matrice<T> & other)
        {
            Matrice temp(other);
            // Réaffectation : on prend les nouvelles données dans Temp, et on lui
            // donne les données à détruire en échange
            swap(temp.nLignes, this->nLignes);
            swap(temp.nColonnes, this->nColonnes);
            swap(temp.representation, this->representation);
     
            return *this;
     
        };

Discussions similaires

  1. Surcharge de l'opérateur d'affectation
    Par PoZZyX dans le forum Windows Forms
    Réponses: 6
    Dernier message: 23/07/2012, 15h30
  2. Surcharge d'opérateurs et affectation
    Par Nadd dans le forum C++
    Réponses: 16
    Dernier message: 20/02/2012, 09h17
  3. Surcharge de l'opérateur new
    Par :Bronsky: dans le forum C++
    Réponses: 17
    Dernier message: 27/10/2010, 21h33
  4. Surcharge de l'opérateur d'affection
    Par ProgVal dans le forum C++
    Réponses: 4
    Dernier message: 06/04/2008, 16h45
  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