1 #ifndef __TABLEAU__ 2 #define __TABLEAU__ 3 4 #include <cstdlib> 5 #include <iostream> 6 using namespace std; 7 8 // Un objet-fonction general, a un parametre 9 template <typename T=float> class Functor1p { 10 public: 11 virtual T operator()(T) const = 0; 12 }; 13 14 template <typename T=float, size_t S=100> class Tableau { 15 public: 16 17 // Le constructeur principal 18 explicit Tableau(); 19 20 // Le trio infernal 21 Tableau (const Tableau & ); 22 Tableau & operator=(const Tableau &); 23 ~Tableau(); 24 25 // Le constructeur de conversion 26 template <typename U> Tableau (const Tableau<U,S>&); 27 28 // renvoie la taille du Tableau 29 size_t size() const { return S;}; 30 31 // renvoie un element du Tableau sans deborder 32 T & operator[](size_t i); 33 34 // meme chose - version const 35 T operator[](size_t i) const; 36 37 // operateurs += 38 // Le parametre est un autre Tableau 39 Tableau & operator+=(const Tableau & ); 40 41 // Le parametre est un T 42 Tableau & operator+=(T ); 43 44 // imprime le Tableau sur la sortie standard 45 void print () const; 46 47 // La fonction transform: on leur passe un objet-fonction à 1 paramètre 48 void transform(const Functor1p<T>& ); 49 50 51 private: 52 T A[S]; 53 54 // Le signe __ rappelle qu'il s'agit de methodes privees 55 void __copie (T src, T dest[]); 56 void __copie (T src[], T dest[]); 57 }; 58 59 // Une fonction qui n'est pas une methode 60 template < typename T,size_t S> Tableau<T, S> operator+(const Tableau<T, S>& t1, const Tableau<T, S>& t2); 61 62 // Le constructeur principal - pas d'allocation memoire a faire ! 63 template <typename T,size_t S> Tableau<T, S>::Tableau() { 64 cerr << "constructeur sz = " << S << '\n'; 65 __copie(0.0,A); 66 }; 67 68 // CE QUI SUIT ETAIT JUSQUE LA DANS LE .cpp 69 70 // Le constructeur de copie - pas d'allocation memoire a faire ! 71 template <typename T,size_t S> Tableau<T, S>::Tableau (const Tableau<T, S> & t) { 72 cerr << "constructeur de copie" << '\n'; 73 __copie(t.A,A); 74 }; 75 76 template <typename T,size_t S> template <typename U> Tableau<T,S>::Tableau (const Tableau<U,S>& t) { 77 //__copie(t.A,A); // Ne compile pas car t.A est PRIVATE 78 for (size_t i=0; i<S; ++i) { 79 A[i] = t[i]; 80 } 81 } 82 83 // L'operateur = PAS D'ALLOCATION DE MEMOIRE, juste gerer les identites 84 template <typename T, size_t S> Tableau<T, S> & Tableau<T, S>::operator=(const Tableau<T, S> &t) { 85 cerr << "operateur =" << '\n'; 86 if (this==&t) // Pour gerer les cas A=A 87 return *this; 88 __copie(t.A,A); 89 return *this; 90 }; 91 92 // Le destructeur: PAS NECESSAIRE ICI 93 template <typename T, size_t S> Tableau<T,S>::~Tableau() { 94 cerr << "destructeur (sz = " << S << ")\n"; 95 }; 96 97 // renvoie un element du tableau sans deborder 98 // pas la peine de tester i < 0, size_t est un type unsigned 99 // (decommentez ce qui suit vous verrez si cela compile) 100 template <typename T,size_t S> T & Tableau<T, S>::operator[](size_t i) { 101 //if (i<0) { 102 // cerr << "ATTENTION Debordement de tableau - je renvoie tableau[0]\n"; 103 // return *A; 104 //} else 105 if (i>= S) { 106 cerr << "ATTENTION Debordement de Tableau - je renvoie Tableau[sz-1]\n"; 107 return A[S-1]; 108 // return *(A+sz-1); // Une autre manière d'écrire la même chose 109 } else { 110 return A[i]; 111 //return *(A+i); 112 }; 113 }; 114 115 // meme chose - version const 116 template <typename T, size_t S> T Tableau<T, S>::operator[](size_t i) const { 117 if (i>= S) { 118 cerr << "ATTENTION Debordement de Tableau - je renvoie Tableau[sz-1]\n"; 119 return A[S-1]; 120 } else { 121 return A[i]; 122 }; 123 }; 124 125 // operateurs += 126 // Le parametre est un autre Tableau 127 template <typename T,size_t S> Tableau<T, S> & Tableau<T, S>::operator+=(const Tableau<T, S> & t) { 128 for (size_t i=0; i < S; i++) { 129 A[i] += t[i]; 130 }; 131 return *this; 132 }; 133 134 // Le parametre est un T 135 template <typename T,size_t S> Tableau<T, S> & Tableau<T, S>::operator+=(T x) { 136 for (size_t i=0; i < S; i++) { 137 A[i] += x; 138 }; 139 return *this; 140 }; 141 142 // imprime le Tableau sur la sortie standard 143 template <typename T,size_t S> void Tableau<T, S>::print () const { 144 for (size_t i=0; i < S; 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,size_t S> void Tableau<T, S>::__copie (T src, T dest[]) 152 { 153 for ( size_t i=0; i< S; i++) { 154 dest[i] = src; 155 } 156 } 157 template <typename T,size_t S> void Tableau<T, S>::__copie (T src[], T dest[]) { 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,size_t S> void Tableau<T, S>::transform(const Functor1p<T>& f ) { 165 for (int i=0; i< S; i++) 166 A[i]=f(A[i]); 167 }; 168 169 template <typename T,size_t S> Tableau<T, S> operator+(const Tableau<T, S>& t1, const Tableau<T, S>& t2) { 170 Tableau<T,S> s; 171 s = t1; 172 s += t2; 173 return s; 174 }; 175 176 #endif