| 12
 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
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 
 | class Tableau
{
    public:
        /* par défaut, on prévoit 10 éléments contigus 
         * ( c'est limite fixée de manière tout à fait arbitraire :D)
         */
        Tableau():size_(10), nextpos_(0), ptr_(new int[10]){}
        /* mais on laisse la possibilité à l'utilisateur d'en prévoir un
         * nombre différent
         */
        Tableau(size_t s):size_(s),nextpos_(0),ptr_(new int[s]){}
        /* le constructeur par copie */
        Tableau(Tableau const & rhs):size_(rhs.size_),nextpos_(rhs.nextpos_),
               ptr_(new int[rhs.size_])
        {
            memcopy(ptr_,rhs.ptr_,size_);
        }
        /* et l'opérateur d'affectation Il utilise le fait que nous passons 
         * le tableau à affecter sous forme de valeur, ce qui implique, 
         * de facto la copie.
         * Le principe mis en oeuvre est le copy 'n swap ;)
         */
        Tableau & operator = (Tableau t)
        {
            std::swap(size_,t.size_);
            std::swap(nextpos_,t.nextpos_);
            std::swap(ptr_,t.ptr_);
            return *this;
        }
        ~Tableau()
        {
            delete[] ptr_;
            ptr_=0;
        }
        /* on permet à l'utilisateur d'ajouter un élément en fin de tableau 
         */
        void push_back(int i)
        {
            /* en doublant chaque fois la taille du tableau si nous avons
             * atteint la limite des éléments possibles, nous évitons
             * de devoir le refaire à chaque insertion
             */
            if(nextpos_==size_)
                resize(size_*2);
            ptr_[nextpos_]=i;
            ++nextpos_;
        }
        /* on permet à l'utilisateur de retirer le dernier élément du tableau 
         */
        void pop_back()
        {
            --nextpos_;
        }
        /* on pourrait aussi lui permettre d'en rajouter en début de tableau,
         * voire d'insérer un élément entre deux éléments existants...
         * Je ne présente pas ces fonctionnalités
         */
        /* on permet à l'utilisateur d'accéder à une valeur grace à
         * l'opérateur []
         * sous la forme non constante
         */
       int & operator[](size_t index){return ptr_[index];}
       /* et sous la forme constante */
       int const & operator[](size_t index){return ptr_[index];}
       /* La fonction at fournit la même possibilité, mais avec un controle
        * de l'index demandé (lance une exception "Overflow" à définir
        * si l'index est hors des limites admises
        */
       int & at(size_t index)
       {
           if(index>=nextpos_)
               throw Overflow();
           return ptr_[index];
       }
       int const & at() const
       {
           if(index>=nextpos_)
               throw Overflow();
           return ptr_[index];
       } 
       /* cette fonction permet de redimensionner le tableau */
       void resize(size_t newsize)
       {
           /* trois possibilités s'offrent à nous:
            *     - soit on rajoute des éléments potentiels,
            *     - soit on redimensionne afin d'en retirer
            *     - soit on ne change pas la taille
            */
           /* si on ne change pas la taille, on ne fait simplement rien */
           if(newsize!=size_)
           {
               /* il nous faut un tableau temporaire à la bonne taille */
               int * temp=new int[newsize];
               /* si la nouvelle taille est plus grande que le nombre
                * d'éléments présents, nous copions nextpos_ elements
                * du tableau d'origine vers le tableau temporaire
                * la position suivante reste inchangée
                */
               if(newsize>nexpos_)
               {
                   memncpy(temp,ptr_,nextpos_*sizeof(int));
               }
               /* sinon, nous copions newsize éléments du tableau d'origine
                * vers le tableau temporaire et
                * la position suivante prend la valeur de newsize
                */
              else
              {
                   memncpy(temp,ptr_,newsize*sizeof(int));
                   nextpos_=newsize;
              }
              /* on termine en libérant la mémoire allouée au tableau 
               * d'origine
               */
             delete [] ptr_;
             /* en définissant la nouvelle taille
              */
             size_=newsize;
             /* et en assignant le tableau temporaire au pointeur réel
              */
             ptr_=temp;
           }
       }
    private:
        size_t size_; // le nombre maximal d'éléments potentiel à 
                      // un instant T
        size_t nextpos_; // la position du prochain élément
        int * ptr_; // le pointeur vers le tableau dont la mémoire est
                    // allouée dynamiquement
}; | 
Partager