1 #ifndef __TABLEAU__ 2 #define __TABLEAU__ 3 4 #include <cstdlib> 5 #include <iostream> 6 #include <stdexcept> 7 using namespace std; 8 9 // Un objet-fonction general, a un parametre 10 template <typename T=float> class Functor1p { 11 public: 12 virtual T operator()(T) const = 0; 13 }; 14 15 template <typename T=float> class Tableau { 16 public: 17 18 // Le constructeur principal - on passe la dimension du tableau en parametre 19 explicit Tableau(size_t ); 20 21 // Le trio infernal 22 Tableau (const Tableau & ); 23 Tableau & operator=(const Tableau &); 24 ~Tableau(); 25 26 // renvoie la taille du Tableau 27 size_t size() const { return sz;}; 28 29 // renvoie un element du Tableau sans deborder 30 T & operator[](size_t i); 31 32 // meme chose - version const 33 T operator[](size_t i) const; 34 35 // operateurs += 36 // Le parametre est un autre Tableau 37 Tableau & operator+=(const Tableau & ); 38 39 // Le parametre est un T 40 Tableau & operator+=(T ); 41 42 // imprime le Tableau sur la sortie standard 43 void print () const; 44 45 // La fonction transform: on leur passe un objet-fonction à 1 paramètre 46 void transform(const Functor1p<T>& ); 47 48 private: 49 const size_t sz; 50 T *A; 51 52 // Le signe __ rappelle qu'il s'agit de methodes privees 53 void __copie (T src, T dest[], size_t s); 54 void __copie (T src[], T dest[], size_t s); 55 }; 56 57 // Une fonction qui n'est pas une methode 58 template < typename T> Tableau<T> operator+(const Tableau<T>& t1, const Tableau<T>& t2); 59 60 // Le constructeur principal - on passe la dimension du tableau en parametre 61 template <typename T> Tableau<T>::Tableau(size_t n): sz(n) { 62 cerr << "constructeur sz = " << n << '\n'; 63 A = (T *) malloc(sz*sizeof(T)); 64 if ( A == NULL ) 65 { 66 throw (bad_alloc()); 67 } 68 __copie(0.0,A,sz); 69 }; 70 71 // CE QUI SUIT ETAIT JUSQUE LA DANS LE .cpp 72 73 // Le constructeur de copie - on fait l'alloc de memoire puis on copie 74 template <typename T> Tableau<T>::Tableau (const Tableau<T> & t): sz(t.sz) { 75 cerr << "constructeur de copie" << '\n'; 76 A = (T *) malloc(sz*sizeof(T)); 77 if ( A == NULL ) 78 { 79 throw (bad_alloc()); 80 } 81 __copie(t.A,A,sz); 82 }; 83 84 // L'operateur = PAS D'ALLOCATION DE MEMOIRE, c'est deja fait !!! 85 template <typename T> Tableau<T> & Tableau<T>::operator=(const Tableau<T> &t) { 86 cerr << "operateur =" << '\n'; 87 if (this==&t) // Pour gerer les cas A=A 88 return *this; 89 90 if (sz != t.sz) { 91 throw (range_error ("Ne peut pas egaliser deux tableaux de tailles differentes")); 92 }; 93 __copie(t.A,A,sz); 94 return *this; 95 }; 96 97 // Le destructeur: rendre la memoire au systeme 98 template <typename T> Tableau<T>::~Tableau() { 99 cerr << "destructeur (sz = " << sz << ")\n"; 100 free(A); 101 }; 102 103 // renvoie un element du tableau sans deborder 104 template <typename T> T & Tableau<T>::operator[](size_t i) { 105 if (i>=sz) { 106 throw (range_error ( "Debordement de Tableau" )); 107 } else { 108 return A[i]; 109 }; 110 }; 111 112 // meme chose - version const 113 template <typename T> T Tableau<T>::operator[](size_t i) const { 114 if (i>=sz) { 115 throw (range_error ( "Debordement de Tableau" )); 116 } else { 117 return A[i]; 118 }; 119 }; 120 121 // operateurs += 122 // Le parametre est un autre Tableau 123 template <typename T> Tableau<T> & Tableau<T>::operator+=(const Tableau<T> & t) { 124 if (sz != t.sz) { 125 throw (range_error ("Ne peut pas egaliser deux tableaux de tailles differentes")); 126 } else { 127 for (size_t i=0; i < sz; i++) { 128 A[i] += t[i]; 129 }; 130 }; 131 return *this; 132 }; 133 134 // Le parametre est un T 135 template <typename T> Tableau<T> & Tableau<T>::operator+=(T x) { 136 for (size_t i=0; i < sz; i++) { 137 A[i] += x; 138 }; 139 return *this; 140 }; 141 142 // imprime le Tableau sur la sortie standard 143 template <typename T> void Tableau<T>::print () const { 144 for (size_t i=0; i < sz; i++) { 145 cout << A[i] << " "; 146 }; 147 cout << '\n'; 148 } 149 150 // copie l'entier src dans la zone memoire pointee par dest 151 template <typename T> void Tableau<T>::__copie (T src, T dest[], size_t s) 152 { 153 for ( size_t i=0; i<s; i++) { 154 dest[i] = src; 155 } 156 } 157 template <typename T> void Tableau<T>::__copie (T src[], T dest[], size_t s) { 158 for (size_t i=0; i<s; i++) { 159 dest[i] = src[i]; 160 }; 161 } 162 163 // La famille de fonction transform: on lui passe un objet-fonction derive de Functor1p 164 template <typename T> void Tableau<T>::transform(const Functor1p<T>& f ) { 165 for (int i=0; i< sz; i++) 166 A[i]=f(A[i]); 167 }; 168 169 template <typename T> Tableau<T> operator+(const Tableau<T>& t1, const Tableau<T>& t2) { 170 Tableau<T> s(t1.size()); 171 if (t1.size() != t2.size()) { 172 cerr << "Ne peut pas ajouter deux Tableaux de tailles differentes" << '\n'; 173 exit(1); 174 } else { 175 s = t1; 176 s += t2; 177 }; 178 return s; 179 }; 180 181 182 #endif