1 #include <cstdlib>
   2 #include "tableau.hpp"
   3 
   4 // Le constructeur principal - on passe la dimension du tableau en parametre
   5 Tableau::Tableau(size_t n): sz(n) {
   6         cerr << "constructeur sz = " << n << '\n';
   7         A = (float *) malloc(sz*sizeof(float));
   8         __copie(0.0,A,sz);
   9 };
  10 
  11 // Le constructeur de copie - on fait l'alloc de memoire puis on copie
  12 Tableau::Tableau (const Tableau & t): sz(t.sz) {
  13         cerr << "constructeur de copie" << '\n';
  14         A = (float *) malloc(sz*sizeof(float));
  15         __copie(t.A,A,sz);
  16 };
  17 
  18 // L'operateur = PAS D'ALLOCATION DE MEMOIRE, c'est deja fait !!!
  19 Tableau & Tableau::operator=(const Tableau &t) {
  20         cerr << "operateur =" << '\n';
  21         if (this==&t)    // Pour gerer les cas A=A
  22                 return *this;
  23         
  24         if (sz != t.sz) {
  25                 cerr << "Ne peut pas egaliser deux tableaux de tailles differentes" << '\n';
  26                 exit(1);
  27         };
  28         __copie(t.A,A,sz);
  29         return *this;
  30 };
  31 
  32 // Le destructeur: rendre la memoire au systeme
  33 Tableau::~Tableau() { 
  34         cerr << "destructeur (sz = " << sz << ")\n";
  35         free(A);
  36 };
  37 
  38 // renvoie un element du tableau sans deborder
  39 // pas la peine de tester i < 0, size_t est un type unsigned
  40 // (decommentez ce qui suit vous verrez si cela compile)
  41 float & Tableau::operator[](size_t i) {
  42         //if (i<0) {
  43         //  cerr << "ATTENTION Debordement de tableau - je renvoie tableau[0]\n";
  44         //  return *A;
  45         //} else
  46         if (i>=sz) {
  47                 cerr << "ATTENTION Debordement de Tableau - je renvoie Tableau[sz-1]\n";
  48                 return A[sz-1];
  49                 // return *(A+sz-1);  // Une autre manière d'écrire la même chose
  50         } else {
  51                 return A[i];
  52                 //return *(A+i);
  53         };
  54 };
  55 
  56 // meme chose - version const
  57 float Tableau::operator[](size_t i) const {
  58         if (i>=sz) {
  59                 cerr << "ATTENTION Debordement de Tableau - je renvoie Tableau[sz-1]\n";
  60                 return A[sz-1];
  61         } else {
  62                 return A[i];
  63         };
  64 };
  65 
  66 // operateurs +=
  67 // Le parametre est un autre Tableau
  68 Tableau & Tableau::operator+=(const Tableau & t) {
  69         if (sz != t.sz) {
  70                 cerr << "Ne peut pas ajouter deux Tableaux de tailles differentes" << '\n'; 
  71                 exit(1);
  72         } else {
  73                 for (size_t i=0; i < sz; i++) {
  74                         A[i] += t[i];
  75                 };
  76         };
  77         return *this;
  78 };
  79 
  80 // Le parametre est un entier
  81 Tableau & Tableau::operator+=(float x) {
  82         for (size_t i=0; i < sz; i++) {
  83                 A[i] += x;
  84         };
  85         return *this;
  86 };
  87 
  88 // imprime le Tableau sur la sortie standard
  89 void Tableau::print () const  {
  90         for (size_t i=0; i < sz; i++) {
  91                 cout << A[i] << " ";
  92         };
  93         cout << '\n';
  94 }
  95 
  96 // copie l'entier src dans la zone memoire pointee par dest
  97 void Tableau::__copie (float src, float dest[], size_t s)
  98 {
  99         for ( size_t i=0; i<s; i++) {
 100                 dest[i] = src;
 101         }
 102 }
 103 void Tableau::__copie (float src[], float dest[], size_t s) {
 104         for (size_t i=0; i<s; i++) {
 105                 dest[i] = src[i];
 106         };
 107 }
 108 
 109 // Deux autres manières d'écrire le même code: difficilement lisible, mais on voit ça souvent
 110 /*
 111 void Tableau::copie (float src, float *dest, size_t s) {
 112         for (size_t i=0; i<s; i++) {
 113                 *(dest++) = src;
 114         };
 115 };
 116 void Tableau::copie (float *src, float *dest, size_t s) {
 117         for (size_t i=0; i<s; i++) {
 118                 *(dest++) = *(src++);
 119         };
 120 }
 121 */
 122 
 123 // La famille de fonctions transform: on leur passe un objet-fonction
 124 // On est obligé de définir autant de fonctions transform qu'il y a de transformations (d'objets-fonctions) définies
 125 void Tableau::transform(const Functor1p& f ) {
 126         for (int i=0; i< sz; i++) 
 127                 A[i]=f(A[i]);
 128 };
 129 
 130 Tableau operator+(const Tableau& t1, const Tableau& t2) {
 131         Tableau s(t1.size());
 132         if (t1.size() != t2.size()) {
 133                 cerr << "Ne peut pas ajouter deux Tableaux de tailles differentes" << '\n'; 
 134                 exit(1);
 135         } else {
 136                 s = t1;
 137                 s += t2;
 138         };
 139         return s;
 140 };
 141