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 :

Classe pour tableau d'entiers à taille variable


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé

    Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 118
    Par défaut Classe pour tableau d'entiers à taille variable
    Bonjour,

    Je veux créer une classe TableauInt qui a pour attributs un tableau d'entiers et sa taille, ainsi que les méthodes suivantes :
    - constructeur sans paramètres
    - constructeur avec la taille
    - destructeur
    - getteur/setteur sur un élement du tableau grâce a l'indice
    - getteur sur la taille
    - saisie
    - affichage

    J'ai donc fait ceci (.h en premier, .cpp en suivant):

    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 TableauInt{
     
        private:
            int* tableau;
            int taille;
     
        public :
            TableauInt();
            TableauInt(int);
            ~TableauInt();
            int getElement(int);
            void setElement(int, int);
            int getTaille();
            void saisie();
            void afficher();
    };
    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
    #include "TableauInt.h"
    #include <iostream>
     
    using namespace std;
     
    TableauInt::TableauInt(): taille(0), tableau(NULL) { }
     
    TableauInt::TableauInt(int t): taille(t), tableau(new int[taille]) { }
     
    TableauInt::~TableauInt() {
        delete [] tableau;
    }
     
     int TableauInt::getElement(int i) {
        return tableau[i];
     }
     
     void TableauInt::setElement(int i, int elt) {
        tableau[i] = elt;
     }
     
      int TableauInt::getTaille() {
        return taille;
     }
     
     void TableauInt::saisie() {
        for (int i=0 ; i < taille ; i++) {
            cout << "Saisir l'entier d'indice " << i << " :     ";
            cin >> tableau[i];
        }
     }
     
    void TableauInt::afficher() {
        for (int i=0 ; i < taille ; i++) {
            cout << tableau[i] << "  ";
        }
    }
    Mais ensuite, je voudrais ajouter un setteur sur la taille : si la nouvelle taille est supérieure a l'ancienne alors on complète le tableau avec des 0, et si elle est inférieure alors on enlève les valeurs dont les indices sont les plus élevés.

    Ma question est: comment faire varier la taille de mon tableau ?

    Merci.

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Tu es sûr de vouloir travailler avec un "int * tableau".

    un "std::vector" serait plus cool (et plus c++ aussi)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre confirmé

    Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 118
    Par défaut
    C'est la deuxième fois qu'on me pose cette question, du coup je prends conscience que ça doit être plus facile de travailler avec vector.
    Malheureusement dans le cadre de mon cours et pour réussir mon examen, c'est "bel et bien" un int* que je dois utiliser ...

    Même si "ça fait pas très C++", j'espère quand même que vous pourrez m'aider.

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par Jéjé34 Voir le message
    Malheureusement dans le cadre de mon cours et pour réussir mon examen, c'est "bel et bien" un int* que je dois utiliser ...
    OK, je me doutais un peu de la réponse mais c'était pour s'assurer

    Citation Envoyé par Jéjé34 Voir le message
    Ma question est: comment faire varier la taille de mon tableau ?
    Pour réallouer, je ne vois que 2 solutions :
    une solution new/delete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    new_table = new (nouvelle taille)
    recopie des éléments de old_table dans new_table
    delete old_table
    old_table = new_table
    une solution à base de realloc/free (plus C que C++ du coup)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    table = realloc(taille)
    table = realloc(nouvelle taille)
    table = realloc(encore nouvelle taille)
    le reallloc retaille la mémoire et recopie en même temps les anciennes données.

    regarde le man realloc() pour voir comment cela marche (PS, ne pas oublier le free du tableau quand tu as fini)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Il faut juste que tu es conscience que tu es en train de recoder std::vector mais en moins bien. (Tu réinventes la roue carrée.)

    Sinon, pour changer la taille de ton tableau, il faut en déclarer un plus grand, recopier l'ancien dans le nouveau et ne surtout pas oublier de supprimer l'ancien.
    Généralement, on travaille avec une taille (la partie utilisée du tableau) et une capacitée (la vraie taille du tableau).
    Lorsqu'on manque de place, il est "courant" d'allouer deux fois l'ancienne taille.

  6. #6
    Membre confirmé

    Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 118
    Par défaut
    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
    void TableauInt::setTaille(int newSize) {
        if (newSize > taille) {
            int* newTable = new int[newSize];
            for (int i=0 ; i < taille ; i++) {
                newTable[i] = tableau[i];
            }
            for (int j=taille ; j < newSize ; j++) {
                newTable[j] = 0;
            }
            delete [] tableau;
            tableau = newTable;
            taille = newSize;
        }
        if (newSize < taille) {
            int* newTable = new int[newSize];
            for (int i=0 ; i < newSize ; i++) {
                newTable[i] = tableau[i];
            }
            delete [] tableau;
            tableau = newTable;
            taille = newSize;
        }
    }
    Je suis parvenu a ça grâce a vos conseils, ça fonctionne.
    Merci à vous.

    PS: Je coche pas "Résolu" toute de suite, j'aurai surement d'autres questions dans la soirée.

  7. #7
    Membre confirmé

    Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 118
    Par défaut
    Quand je fais ceci dans le main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    TableauInt T1(3);
        T1.saisie();
        T1.afficher();
     
        TableauInt T2(T1);
        T2.afficher();
    Le programme plante lors de son exécution, apparemment le constructeur par copie défini par defaut ne convient pas.
    Je n'arrive pas a comprendre pourquoi.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par Ehonn Voir le message
    Il faut juste que tu es conscience que tu es en train de recoder std::vector mais en moins bien. (Tu réinventes la roue carrée.)
    C'est dans un but scolaire, il faut bien passer par là.
    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.

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Il faut juste faire attention au fait que ta classe TableauInt a, typiquement, sémantique de valeur, dans le sens où tu voudras sans doute pouvoir faire quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    TableauInt tab1(10);
     
    /*... */
     
    TableauInt tab2 = tab1;
    /* ... */
     
    /* ou */
    TableauInt tab3(tab1);
    Ton code en son état actuel va poser des problèmes aussi bien pour tab2 que pour tab3

    Je m'explique:

    Si l'on regarde le destructeur de ta classe, on se rend compte qu'il est implémenté sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    TableauInt::~TableauInt() {
        delete [] tableau;
    }
    ce qui est la manière correcte de l'implémenter, pour éviter les fuites mémoire.

    Seulement, il faut savoir qu'un certain Coplien a déterminé il y a déjà ... ouh, de nombreuses années, le fait qu'une classe devrait présenter quatre comportements majeurs:
    1. la possibilité de se construire (fournie par les constructeurs que tu as implémentés)
    2. la possibilité de se copier
    3. la possibilité d'être réaffectée (l'opérateur "=")
    4. la possibilité de se détruire (fournie par le destructeur que tu as implémenté)
      (pour être précis, il a fourni plusieurs formes différentes, mais c'est celle qui nous intéresse ici, et elle est connue sous le nom de "forme canonique orthodoxe de Coplien )
    Et c'est là que les choses deviennent intéressantes.

    En effet, le compilateur va, sauf ordre contraire de ta part (comprends: si tu ne fournis pas une implémentation personnelle de ces quatre comportement), implémenter ces quatre comportements de manière triviale:
    • le constructeur par copie se contentera de copier les membres de ton objet, dans l'ordre de leur déclaration
    • L'opérateur d'affectation se contentera de faire une affectation des différents membres (dans l'ordre de leur déclaration, toujours) avant de renvoyer ce qui est pointé par this
    • le destructeur se contentera de détruire les différents membres dans l'ordre inverse de leur déclaration.
    Comme tu as fourni une implémentation personnelle (et tout à fait juste au demeurant) pour le destructeur, et plusieurs implémentation personnelles pour le constructeur, ce sont ces implémentations personnelles qui seront utilisées, mais le compilateur fournira sa propre implémentation triviale pour le constructeur par copie (TableauInt(TableauInt const &)) et pour l'opérateur d'affectation (TableauInt & operator = (TableauInt const &)).

    Et c'est là que les problèmes vont commencer

    Pour bien comprendre ces problèmes, il faut avoir conscience de ce que sont réellement les pointeurs : ce ne sont jamais que des variables de type numérique (souvent non signées, d'ailleurs) qui correspondent à l'adresse à laquelle on pourra accéder à un élément du type indiqué (et tant pis si tu en avait conscience, un petit rappel n'est jamais superflu )

    Le fait, c'est que lorsque le compilateur va copier (ou affecter) ce pointeur, il ne va copier (ou affecter) que le pointeur (autrement dit l'adresse représentée par le pointeur d'origine) et ne va absolument rien faire en ce qui concerne la donnée sous-jacente, et ca va occasionner une série de problèmes...

    Mon code va mettre tous les problèmes en évidences
    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
    int main()
    {
        TableauInt tab(10);
        tab.setElement(2,15); // getElement(2) == 15 ;)
        if(/* une condition quelconque */)
        {
            TableauInt tab2 = tab; // on croit avoir un autre tableau indépendant de tab
            tab2.setElement(2,20); // sauf que setElement travaille avec la même adresse
                                   // pour ses différents éléments que tab
            // tab.getElement() == 15 ? non! tab.getElement() == ... 20
        } //CRACK : tab2 est détruit (~TableauInt automatiquement appelé pour tab2
         // ce qui implique delete[] tab2::tableau et comme tab2::tableau == tab::tableau ... )
        /* ...*/
        return 0; // tab est détruit (BOUM :~TableauInt automatiquement appelé pour tab
                  // ce qui implique delete[] tab::tableau... qui a été libéré en meme temps 
                  // que tab2::tableau)
    }
    Le comportement observé dans le commentaire de la ligne 10 est, en soi, déjà fort embêtant (*), mais le gros problème prend sa source à la ligne 11 et trouve son épilogue à la ligne 14 car la tentative de libération d'une adresse mémoire déjà libérée provoque un comportement indéfini (souvent indiqué par une erreur de segmentation )
    (*) on se serait en effet attendu à ce que tab.getElement(2) renvoie 15 et tab2.getElement(2) 20, non

    Il est donc temps de rajouter une règle en corolaire à la forme canonique orthodoxe de Coplien.

    Cette règle est connue sous le nom de big rule of three, ou, si tu préfères en français, la "grande règle des trois".

    Cette règle nous dit que si tu as du fournir une implémentation spécifique pour n'importe quelle fonction parmi le constructeur par copie, l'opérateur d'affectation ou le destructeur, alors, il faut que tu fournisse une implémentation spécifique adaptée pour les trois.

    Autrement dit : comme tu as fourni une implémentation spécifique pour le destructeur, tu dois penser à fournir une implémentation spécifique pour le constructeur par copie et pour l'opérateur d'affectation.

    Commençons par le constructeur par copie.

    L'idée du constructeur par copie est de permettre un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
        TableauInt tab(3);
        TableauInt tab2(tab);
        /* tab et tab2 gèrent chacun leurs propres valeurs de manière indépendante */
        /* ... */
        return 0;
    }
    Pour y arriver, bah, c'est *relativement* simple : "YAKA" veiller à ce que le constructeur par copie fasse une copie en profondeur du pointeur d'origne.

    Pour ta classe TableauInt, cela pourrait ressembler à quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    TableauInt::TableauInt(TableauInt const & rhs):tableau(rhs.taille!=0? new int[rhs.taille] : NULL),taille(rhs.taille)
    {
        memncpy(tableau, rhs.tableau, taille * sizeof(int));
    }
    Enfin, pour comprendre la raison pour laquelle il faut redéfinir aussi l'opérateur d'affectation (et par la même occasion, comment s'y prendre), réfléchissons un peu à ce qui se passerait avec le 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
    int main()
    {
        TableauInt tab(10);
        /* ...*/
        TableauInt tab2(20); // aucun problème : tab2::tableau != tab::tableau
        tab.setElement(2,10);
        tab2.setElement(2,15);
        /* ...*/
        tab = tab2; // 1- CRACK tab::tableau == tab2::tableau, mais on a perdu toute référence
                    // au tab::tableau d'origine ==> fuite mémoire
                    // 2- CRACK tab::tableau == tab2::tableau
        tab.setEment(2,20);
        /* OUCH... tab2.getElement(2) == 15 ? non!!! tab2.getElement(2) == 20 
         */
        /* ...*/
        return 0; // BOUM : tab2 est détruit en premier (~TableauInt appelé pour
                  // tab2 ce qui équivaut à delete [] tab2::tableau)
                  // tab est détruit en second (~TableauInt appelé pour
                  // tab ce qui équivaut à delete [] tab::tableau et comme
                  // tab::tableau == tab2::tableau ==>double libération de la mémoire)
    }
    Hé oui...

    Dans le meilleur des cas, ton application plantera au moment de quitter, à cause de la double tentative de la mémoire.

    C'est déjà assez embêtant pour essayer de l'éviter, mais, en plus, on observe une fuite mémoire, et ca, c'est de nature à rendre tout ton système instable, ce qui est encore moins agréable

    Et je ne parle pas du désagrément observé au niveau de getElement re

    Par chance, il existe un idiome appelé copy-and-swap qui permet de résoudre tous ces problèmes.

    L'idée, lorsque l'on veut assigner un objet à un autre, c'est de faire en interne (comprends : au niveau de l'opérateur d'affectation) une copie de l'objet assigné (comprends : celui qui se trouve à droite du =), puis d'intervertir les membres de l'objet courent avec ceux de la copie.

    Comme l'opérateur d'affectation n'est jamais qu'une fonction et que la copie n'est jamais qu'une variable locale à cette fonction, la copie sera correctement détruite (et son destructeur appelé) au moment de quitter la dite fonction.

    Comme nous aurons interverti le pointeur d'origine de l'objet courent et celui de la copie, la mémoire correspondant au pointeur d'origine sera correctement libérée.

    Et comme nous aurons agit sur une copie de l'objet assigné, il y aura déjà eu une copie en profondeur du pointeur, ce qui fait que tab et tab2 (selon mon exemple) utiliseront bel et bien deux adresses différentes

    Enfin, voyons un peu comment nous y prendre

    L'idéal est de rajouter une fonction membre "swap" qui intervertira les différents membres entre eux.

    Vu que c'est pour l'apprentissage, je vais te présenter différents moyens "faits main", mais le résultat sera identique
    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
    void TableauInt::swap(TableauInt & rhs)
    {
        int * tabtemp= tableau; 
        tableau = rhs.tableau;
        rhs.tableau = temp
        int tailleTemp = taille;
        taille = rhs.taille;
        rhs.taille = tailleTemp;
    }
    /* OU - OU - OU - en utilisant XOR */
    void TableauInt::swap(TableauInt & rhs)
    {
        tableau ^=  rhs.tableau;
        rhs.tableau ^= tableau;
        tableau ^= rhs.tableau;
        taille^=  rhs.taille;
        rhs.taille^= taille;
        taille^= rhs.taille;
    }
    Mais la STL nous fournit une fonction swap, disponible dans l'espace de noms std par simple inclusion du fichier <algorithme> et l'on pourrait donc envisager d'écrire cette fonction sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void TableauInt::swap(TableauInt & rhs)
    {
        std::swap(tableau, rhs.tableau);
        std::swap(taille, rhs.taille);
    }
    Et, enfin, nous redéfinirions l'opérateur d'affectation sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    TableauInt & operator = (TableauInt const & rhs)
    {
       TableauInt temp(rhs); // copie de l'élément affecté
       swap(temp); //inversion des membre de this avec la copie
       return *this; // renvoie une référence sur l'élément courent
                     // la copie est détruite en sortant de la fonction
    }
    Et maintenant, tout fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int main()
    {
        TableauInt tab(10);
        tab.setElement(2,10);
        Tableauint tab2(tab); //tab2.getElement(2) == 10
        tab2.setElement(2,20) // tab2.getElement(2) == 20, tab.getElement(2) == 10
        Tableauint tab3(15);
        tab3 = tab; // pas de fuite mémoire, tab3.getElement(2) == 10
        tab.setElement(2,5); tab.getElement(2) == 5, tab3.getElement == 10
        return 0;
    } // destruction de tab3
      // destruction de tab2
      // destruction de tab
      // aucun problème parce que chaque tableau manipule une adresse qui lui est propre
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre confirmé

    Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 118
    Par défaut
    Resolu ✓

    Merci koala01, et aux autres avant lui !

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Juste une chose pour le copy-and-swap: prendre directement la source par valeur peut éviter la copie quand on utilise l'opérateur = avec un temporaire:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    TableauInt::TableauInt& operator=(TableauInt tmp) {
    	swap(tmp);
    	return *this;
    }
    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.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 25/04/2015, 15h51
  2. Classe pour tableau HTML
    Par gui80 dans le forum Langage
    Réponses: 14
    Dernier message: 25/09/2008, 09h04
  3. javascript pour tableau à largeur de colonnes variables
    Par barkleyone dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 06/06/2006, 17h14
  4. Comment obtenir un tableau à taille variable ?
    Par marsupilami34 dans le forum Langage
    Réponses: 6
    Dernier message: 27/06/2005, 15h03
  5. Réponses: 10
    Dernier message: 15/03/2005, 10h31

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