Você está na página 1de 8

Correction TP5

Question 1 : classe vecteur générique


Comme toutes les implémentations des fonctions génériques se trouvent dans le fichier d’entête et que l’on a
déclaré inline les deux fonctions non génériques (stop et test_dim), il n’est pas utile de conserver le fichier
d’implémentation (.cpp) :

#i f n d e f vecteurT_hpp
#define vecteurT_hpp

#include <i o s t r e a m >


#include <complex>
using namespace s t d ;

// u t i l i t a i r e s
i n l i n e void s t o p ( const char ∗ msg ) // message d ’ a r r ê t
{ c o u t << "ERREUR␣ c l a s s e ␣ vecteurT , ␣ " << msg ; e x i t ( −1); }
i n l i n e void test_dim ( i n t d1 , i n t d2 , const char ∗ o r g ) // t e s t dimension
{
i f ( d1==d2 ) return ;
c o u t << o r g << " ␣ ( " << d1 << " , " << d2 << " ) ␣ d i m e n s i o n s ␣ i n c o m p a t i b l e s " ;
e x i t ( −1);
}

/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
CLASSE GENERIQUE v e c t e u r <T>
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
− c o n s t r u c t e u r par d é f a u t , dimension e t v a l e u r e t par c o p i e
− a c c è s en l e c t u r e e t é c r i t u r e à un é l é m e n t
− i m p r e s s i o n du v e c t e u r
− somme e t d i f f é r e n c e de deux v e c t e u r s ( e x t e r n e s à l a c l a s s e )
− p r o d u i t par un s c a l a i r e ( e x t e r n e à l a c l a s s e )
− p r o d u i t s c a l a i r e e t norme e u c l i d i e n n e ( e x t e r n e à l a c l a s s e )
− o p é r a t e u r s : = s i m i l a i r e au c o n s t r u c t e u r par c o p i e
( i ) a c c è s au i ème é l é m e n t
+ − u n a i r e (U=−V)
+= −= ∗= /= d ’ un s c a l a i r e
+ − ∗ = un s c a l a i r e ( e x t e r n e )
+ − un v e c t e u r ( e x t e r n e )
== !=
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗/
template<typename T>
class vecteur
{
protected :
i n t dim_ ; // dimension du v e c t e u r
T ∗ val_ ; // t a b l e a u x de v a l e u r s
public :
v e c t e u r ( i n t d=0 , const T& v0=T ( ) ) ; // dim e t v a l c o n s t a n t e
v e c t e u r ( const v e c t e u r <T>& v ) ; // c o n s t r u c t e u r par c o p i e
~ vecteur ( ) ;
// t o o l s
void i n i t ( i n t d ) ; // a l l o c a t i o n
void c l e a r ( ) ; // d é s a l l o c a t i o n

// o p é r a t e u r d ’ a f f e c t a t i o n
v e c t e u r & operator=(const v e c t e u r <T>& v ) ; // a f f e c t a t i o n d ’ un v e c t e u r
v e c t e u r & operator=(const T& x ) ; // a f f e c t a t i o n d ’ une v a l e u r

// o p é r a t e u r s d ’ a c c è s
T operator ( ) ( i n t i ) const { return val_ [ i − 1 ] ; } // v a l e u r 1−>dim ( i n d i c e non t e s t é )
T& operator ( ) ( i n t i ) { return val_ [ i − 1 ] ; } // r é f é r e n c e 1−>dim ( i n d i c e non t e s t é )
i n t dim ( ) const { return dim_ ; } // a c c è s dimension

// o p é r a t e u r s a l g é b r i q u e s
v e c t e u r <T>& operator +=(const v e c t e u r <T>& v ) ; // u += v
v e c t e u r <T>& operator −=(const v e c t e u r <T>& v ) ; // u −= v
v e c t e u r <T>& operator +=(const T& x ) ; // u += x
v e c t e u r <T>& operator −=(const T& x ) ; // u −= x
v e c t e u r <T>& operator ∗=( const T& x ) ; // u ∗= x
v e c t e u r <T>& operator /=( const T& x ) ; // u /= x
} ; // f i n de d é f i n i t i o n de l a c l a s s e

//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

2
// IMPLEMENTATION DES FONCTIONS MEMBRES
//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
// c o n s t r u c t e u r s −d e s t r u c t e u r
template<typename T>
v e c t e u r <T> : : v e c t e u r ( i n t d , const T& v0 ) //dim e t v a l c o n s t a n t e
{
i n i t (d ) ;
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]= v0 ;
}
template<typename T>
v e c t e u r <T> : : v e c t e u r ( const v e c t e u r <T>& v ) // c o n s t r u c t e u r par c o p i e
{
i n i t ( v . dim_ ) ;
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]=v . val_ [ i ] ;
}
template<typename T>
v e c t e u r <T> : : ~ v e c t e u r ( )
{ clear (); }

template<typename T>
void v e c t e u r <T> : : i n i t ( i n t d ) // i n i t i a l i s a t i o n a v e c a l l o c a t i o n dynamique
{
i f ( d<0) s t o p ( " i n i t ( ) ␣ : ␣ d i m e n s i o n ␣<0" ) ;
dim_=d ;
val_ =0;
i f ( d>0) val_ = new T [ d ] ;
}
template<typename T>
void v e c t e u r <T> : : c l e a r ( ) // d é s a l l o c a t i o n
{
i f ( val_ !=0) delete [ ] val_ ;
dim_=0;
}

// a f f e c t a t i o n
template<typename T>
v e c t e u r <T> & v e c t e u r <T> : : operator=(const v e c t e u r <T>& v ) // a f f e c t a t i o n d ’ un v e c t e u r <T>
{
i f ( dim_!=v . dim_ ) // redimensionnement
{
clear ();
i n i t ( v . dim_ ) ;
}
// r e c o p i e
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]=v . val_ [ i ] ;
return ∗ t h i s ;
}
template<typename T>
v e c t e u r <T> & v e c t e u r <T> : : operator=(const T& x ) // a f f e c t a t i o n d ’ une v a l e u r
{
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]=x ;
return ∗ t h i s ;
}

// o p é r a t e u r s a l g é b r i q u e s
template<typename T>
v e c t e u r <T>& v e c t e u r <T> : : operator +=(const v e c t e u r <T>& v )
{
test_dim ( dim_ , v . dim_ , " op ␣+=" ) ;
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]+=v . val_ [ i ] ;
return ∗ t h i s ;
}
template<typename T>
v e c t e u r <T>& v e c t e u r <T> : : operator −=(const v e c t e u r <T>& v )
{
test_dim ( dim_ , v . dim_ , " op ␣−=" ) ;
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]−=v . val_ [ i ] ;
return ∗ t h i s ;
}
template<typename T>
v e c t e u r <T>& v e c t e u r <T> : : operator +=(const T& x )
{
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]+=x ;
return ∗ t h i s ;
}
template<typename T>
v e c t e u r <T>& v e c t e u r <T> : : operator −=(const T& x )

3
{
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]−=x ;
return ∗ t h i s ;
}
template<typename T>
v e c t e u r <T>& v e c t e u r <T> : : operator ∗=( const T& x )
{
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]∗= x ;
return ∗ t h i s ;
}
template<typename T>
v e c t e u r <T>& v e c t e u r <T> : : operator /=( const T& x )
{
i f ( x==T ( ) ) s t o p ( " op ␣/=␣ : ␣ d i v i s i o n ␣ par ␣ 0 " ) ;
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]/= x ;
return ∗ t h i s ;
}

//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
// DEFINITION ET IMPLEMENTATION DES FONCTIONS/OPERATEURS EXTERNES
//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
// o p é r a t e u r s e x t e r n e s
template<typename T> v e c t e u r <T> operator+(const v e c t e u r <T>& u ) // +u
{ return u ; }
template<typename T> v e c t e u r <T> operator −(const v e c t e u r <T>& u ) // −u
{ v e c t e u r <T> w=u ; return w∗= −1.; }
template<typename T> v e c t e u r <T> operator+(const v e c t e u r <T>& u , const v e c t e u r <T>& v ) // u+v
{ v e c t e u r <T> w=u ; return w+=v ; }
template<typename T> v e c t e u r <T> operator −(const v e c t e u r <T>& u , const v e c t e u r <T>& v ) // u−v
{ v e c t e u r <T> w=u ; return w−=v ; }
template<typename T> v e c t e u r <T> operator+(const v e c t e u r <T>& u , const T& x ) // u+x
{ v e c t e u r <T> w=u ; return w+=x ; }
template<typename T> v e c t e u r <T> operator −(const v e c t e u r <T>& u , const T& x ) // u−x
{ v e c t e u r <T> w=u ; return w−=x ; }
template<typename T> v e c t e u r <T> operator ∗ ( const v e c t e u r <T>& u , const T& x ) // u∗ x
{ v e c t e u r <T> w=u ; return w∗=x ; }
template<typename T> v e c t e u r <T> operator / ( const v e c t e u r <T>& u , const T& x ) // u/ x
{ v e c t e u r <T> w=u ; return w/=x ; }
template<typename T> v e c t e u r <T> operator+(const T& x , const v e c t e u r <T>& u ) // x+u
{ v e c t e u r <T> w=u ; return w+=x ; }
template<typename T> v e c t e u r <T> operator −(const T& x , const v e c t e u r <T>& u ) // x−u
{ v e c t e u r <T> w=−u ; return w−=x ; }
template<typename T> v e c t e u r <T> operator ∗ ( const T& x , const v e c t e u r <T>& u ) // x ∗u
{ v e c t e u r <T> w=u ; return w∗=x ; }
template<typename T> T operator | ( const v e c t e u r <T>& u , const v e c t e u r <T>& v ) // u | v
{
test_dim ( u . dim ( ) , v . dim ( ) , " op ␣ | " ) ;
T s =0;
f o r ( i n t i =1; i <=u . dim ( ) ; i ++) s+=u ( i ) ∗ v ( i ) ;
return s ;
}
template<typename T>
T norme ( const v e c t e u r <T>& u ) // s q r t ( u | u )
{ return s q r t ( u | u ) ; }

// o p é r a t e u r s de comparaison
template<typename T>
bool operator==(const v e c t e u r <T>& u , const v e c t e u r <T>& v )
{
i f ( u . dim ( ) ! = v . dim ( ) ) return f a l s e ;
f o r ( i n t i =1; i <=u . dim ( ) ; i ++)
i f ( u ( i )!= v ( i ) ) return f a l s e ;
return true ;
}
template<typename T>
bool operator !=( const v e c t e u r <T>& u , const v e c t e u r <T>& v )
{ return ! ( u==v ) ; }

// o p é r a t e u r de f l u x
template<typename T>
ostr ea m & operator<<(os tr ea m& os , const v e c t e u r <T>& u )
{
i f ( u . dim()<=0) { o s << " ( ) " ; return o s ; }
o s << " ( " ;
f o r ( i n t i =1; i <u . dim ( ) ; i ++) o s << u ( i ) << " , " ;
o s << u ( u . dim ( ) ) << " ) " ;
return o s ;

4
}

Question 2 : Programme principal, validation en réel et en complexe


//===========================================================================
// Programmation g é n é r i q u e
//===========================================================================
#include <complex>
#include " v e c t e u r T . hpp "

using namespace s t d ;
typedef complex<double> complexe ; // a l i a s

i n t main ( )
{
// t e s t a v e c d e s d o u b l e
//=====================
c o u t << " Test ␣ en ␣ r e e l \n " ;
// t e s t d e s c o n s t r u c t e u r s
v e c t e u r <double> V1 ;
v e c t e u r <double> V2 ( 3 ) ;
v e c t e u r <double> V3 ( 3 , 1 ) ;
v e c t e u r <double> V4(V3 ) ;
// t e s t i m p r e s s i o n
c o u t << "V1␣ : ␣ " << V1 << e n d l ;
c o u t << "V2␣ : ␣ " << V2 << e n d l ;
c o u t << "V3␣ : ␣ " << V3 << e n d l ;
c o u t << "V4␣ : ␣ " << V4 << e n d l ;
// t e s t a c c è s
V2 ( 1 ) = 1 . ; V2 ( 2 ) = 2 . ; V2 ( 3 ) = 3 . ;
c o u t << " a c c e s ␣ : ␣V2␣ : ␣ " << V2 << e n d l ;
v e c t e u r <double> V5 ;
V5=V2 ;
c o u t << "V5=V2␣ : ␣ " << V5 << e n d l ;
// t e s t de l a somme e t d i f f é r e n c e , p r o d u i t
v e c t e u r <double> V6 , V7 , V8 ;
V6=V2+V3 ;
c o u t << " somme␣V6=V2+V3␣ : ␣ " << V6 << e n d l ;
V7=V2−V3 ;
c o u t << " d i f f e r e n c e ␣V7=V2−V3␣ : ␣ " << V7 << e n d l ;
V8=V2 ∗ 5 . ;
c o u t << " p r o d u i t ␣V8=V2∗5 ␣ : ␣ " << V8 << e n d l ;
V8=5.∗V2 ;
c o u t << " p r o d u i t ␣V8=5∗V2␣ : ␣ " << V8 << e n d l ;
v e c t e u r <double> V9=3.∗V8+(2.∗V6−V5 ) / 2 . ;
c o u t << " c o m b i n a i s o n ␣V9=3.∗V8+(2.∗V6−V5 ) / 2 . ␣ : ␣ " << V9 << e n d l ;
V9=−V9 ;
c o u t << " oppose ␣V9=−V9␣ : ␣ " << V9 << e n d l ;
c o u t << "V2 | V3=" << (V2 | V3) << e n d l ;
c o u t << " norme (V2)= " << norme (V2) << e n d l ;

// t e s t a v e c d e s c o m p l e x e s
//=======================
c o u t << " \ nTest ␣ en ␣ complexe \n " ;
complexe i ( 0 . , 1 . ) ;
v e c t e u r <complexe> Z1 ( 3 , i ) ; c o u t << " v e c t e u r ␣Z1␣ : ␣ " << Z1 << e n d l ;
v e c t e u r <complexe> Z2 ( 3 , 1 ) ; c o u t << " v e c t e u r ␣Z2␣ : ␣ " << Z2 << e n d l ;
v e c t e u r <complexe> Z3 ( 3 ) ;
f o r ( i n t j =1; j <=3; j ++) Z3 ( j )= complexe ( j ) ;
c o u t << " v e c t e u r ␣Z3␣ : ␣ " << Z3 << e n d l ;
v e c t e u r <complexe> Z=Z1+Z2−Z3 ; c o u t << " v e c t e u r ␣Z=Z1+Z2−Z3␣ : ␣ " << Z << e n d l ;
Z=i ∗Z1−Z2∗ i ; c o u t << " v e c t e u r ␣Z=i ∗Z1−i ∗Z2␣ : ␣ " << Z << e n d l ;
c o u t << " ( Z1 | Z2)= " << ( Z1 | Z2 ) << e n d l ;
c o u t << " norme ( Z1)= " << norme ( Z1 ) << e n d l ;
return 0 ;
}
//============================= F I N ===================================

Résultats
Test en reel
V1 : ()
V2 : (0,0,0)
V3 : (1,1,1)
V4 : (1,1,1)
acces : V2 : (1,2,3)

5
V5=V2 : (1,2,3)
somme V6=V2+V3 : (2,3,4)
difference V7=V2-V3 : (0,1,2)
produit V8=V2*5 : (5,10,15)
produit V8=5*V2 : (5,10,15)
combinaison V9=3.*V8+(2.*V6-V5)/2. : (16.5,32,47.5)
oppose V9=-V9 : (-16.5,-32,-47.5)
V2|V3=6
norme(V2)=3.74166
Test en complexe
vecteur Z1 : ((0,1),(0,1),(0,1))
vecteur Z2 : ((1,0),(1,0),(1,0))
vecteur Z3 : ((1,0),(2,0),(3,0))
vecteur Z=Z1+Z2-Z3 : ((0,1),(-1,1),(-2,1))
vecteur Z=i*Z1-i*Z2 : ((-1,-1),(-1,-1),(-1,-1))
(Z1|Z2)=(0,3)
norme(Z1)=(0,1.73205)

Question 3 : produit scalaire réel et complexe


Lorsque le type T est un complexe, le produit scalaire (opérateur |) proposé précédemment ne correspond
pas au produit hermitien et par conséquent la norme construite à partir de ce produit scalaire n’est pas
correcte pour un vecteur complexe. Une façon de résoudre ce problème consiste à surcharger l’opérateur |
pour des objets de type vecteur<complex<T> > :
// p r o d u i t h e r m i t i e n pour d e s v e c t e u r s c o m p l e x e s
template <c l a s s T>
complex<T> operator | ( const v e c t e u r <complex<T> >& Z1 , const v e c t e u r <complex<T> >& Z2 )
{
test_dim ( Z1 . dim ( ) , Z2 . dim ( ) , " op ␣Z1 | Z2 " ) ;
complex<T> r =0;
f o r ( i n t i =1; i <=Z1 . dim ( ) ; i ++) r+=Z1 ( i ) ∗ c o n j ( Z2 ( i ) ) ;
return r ;
}

Question 4 : norme retournant un réel


La fonction norme définie précédemment utilisera naturellement ce produit scalaire pour des vecteurs de type
vecteur<complex<T> > mais, compte-tenu de sa définition, elle retournera un complex<T> ! Ce qui n’est pas
très naturelle pour une norme qui devrait retourner un réel (en fait un objet de type T). C’est pourquoi, on
surcharge également la fonction norme de la façon suivante :
// norme r e t o u r n a n t un r é e l pour d e s c o m p l e x e s
template <c l a s s T>
T norme ( const v e c t e u r <complex<T> > &V) // norme e u c l i d i e n n e d ’ un v e c t e u r complexe
{ return s q r t ( (V|V ) . r e a l ( ) ) ; }

Noter que le compilateur choisi toujours la version générique la mieux adaptée et donc ici l’opérateur | sur
des objets vecteur<complex<T> >.

Question 5 : opérations mélangeant des complexes et des réels


Afin de prendre en compte des objets de type réel dans des objets de type complexes, il suffit d’étendre à un
type différent (template C) certaines fonctionnalités de la classe :
template<typename T>
class vecteur
{
private :
i n t dim_ ; // dimension du v e c t e u r
T ∗ val_ ; // t a b l e a u x de v a l e u r s
public :
template<typename C> v e c t e u r ( i n t d=0 , const C& v0=C ( ) ) ; //dim e t v a l c o n s t a n t e
template<typename C> v e c t e u r ( const v e c t e u r <C>& v ) ; // c o n s t r u c t e u r par c o p i e
~ vecteur ( ) ;
// t o o l s
void i n i t ( i n t d ) ; // a l l o c a t i o n
void c l e a r ( ) ; // d ï ¿ ½ s a l l o c a t i o n
// o p e r a t e u r d ’ a s s i g n a t i o n
template<typename C> v e c t e u r & operator=(const v e c t e u r <C>& v ) ; // = v e c t e u r <C>
template<typename C> v e c t e u r & operator=(const C& x ) ; // = C

6
// o p e r a t e u r s d ’ a c c e s
T operator ( ) ( i n t i ) const { return val_ [ i − 1 ] ; } // v a l e u r 1−>dim ( i n d i c e non t es t é )
T& operator ( ) ( i n t i ) { return val_ [ i − 1 ] ; } // référence 1−>dim ( i n d i c e non t es t é )
i n t dim ( ) const { return dim_ ; } // accès dimension
// o p e r a t e u r s a l g e b r i q u e s
template<typename C> v e c t e u r <T>& operator +=(const v e c t e u r <T>& v ) ; // u += v<C>
template<typename C> v e c t e u r <T>& operator −=(const v e c t e u r <T>& v ) ; // u −= v<C>
template<typename C> v e c t e u r <T>& operator +=(const T& x ) ; // u += c
template<typename C> v e c t e u r <T>& operator −=(const T& x ) ; // u −= c
template<typename C> v e c t e u r <T>& operator ∗=( const T& x ) ; // u ∗= c
template<typename C> v e c t e u r <T>& operator /=( const T& x ) ; // u /= c
};

Noter la syntaxe qui permet à une fonction membre de prendre un type d’argument différent :
template<typename C> v e c t e u r <T>& operator +=(const v e c t e u r <C>& v )

L’implementation se fera alors de la façon suivante :


template<typename T> template<typename C>
v e c t e u r <T>& v e c t e u r <T> : : operator +=(const v e c t e u r <C>& v ) }
{ test_dim ( dim_ , v . dim_ , " op ␣+=" ) ;
f o r ( i n t i =0; i <dim_ ; i ++) val_ [ i ]+=v . val_ [ i ] ;
return ∗ t h i s ;
}

le premier template faisant référence à celui de la classe et le second à celui de la fonction membre.

Attention, cette approche suppose que la conversion du type C en type T soit permise. Ce qui est le cas pour
un double vers un complex<double> mais pas le cas complex<double> vers double. Par conséquent, il y
aura une erreur de compilation dès que cette fonction sera instanciée avec T=double et C=complex<double>,
par exemple avec les instructions suivantes dans le main :

vecteur<double> R(3,0); R+=complex<double>(1.,0.).

Cette erreur de compilation est positive car elle prévient d’une utilisation abusive de type. Cependant, dans
certains cas, il peut y avoir une instanciation de ce type à la compilation même si de telles instructions
n’apparaissent pas et dans ce cas il y a une erreur de compilation qu’il y a moyen d’éviter en contrôlant
soi-même ces transtypages. Il suffit de produire les spécialisations pouvant poser problème. Ainsi on pourra
ajouter dans l’implémentation la spécialisation :
template <>
v e c t e u r <double>& v e c t e u r <double > : : operator +=(const complex<double>& z )
{ cout<<" v e c t e u r : : + = : t r a n s t y p a g e ␣ i n c o r r e c t ␣ de ␣ comple xe ␣ en ␣ r ï ¿ ½ e l " ; e x i t ( 1 ) ; }

On notera la syntaxe particulière template<> indiquant qu’il y a une spécialisation totale de la fonction.

Question 6 : classe matrice héritant de vecteur


Ajout dans le fichier vecteurT.hpp :
/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
CLASSE GENERIQUE m a t r i c e <T> h é r i t a n t de v e c t e u r <T>
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
m a t r i c e c a r r é e d ’ o r d r e d r a n g é e en l i g n e
− c o n s t r u c t e u r par d é f a u t , dimension e t v a l e u r e t par c o p i e
− a c c è s en l e c t u r e e t é c r i t u r e à un c o e f f i c i e n t
− a f f i c h a g e de l a m a t r i c e
− opérateurs : ( i , j ) a c c è s au c o e f f i c i e n t i , j >=1
+= −= d ’ une m a t r i c e
∗= /= d ’ un s c a l a i r e
+ − u n a i r e (A=−B)
+ − matrices ( externe )
∗ / a v e c un s c a l a i r e
p r o d u i t m a t r i c e −v e c t e u r
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗/
template<typename T>
c l a s s m a t r i c e : public v e c t e u r <T>
{
public :
int d ;
m a t r i c e ( i n t di , const T& v0=T ( ) )
: v e c t e u r <T>( d i ∗ di , v0 ) , d ( d i ) {}

7
T& operator ( ) ( i n t i , i n t j )
{ return this−>val_ [ ( i −1)∗d+j − 1 ] ; }
const T& operator ( ) ( i n t i , i n t j ) const
{ return this−>val_ [ ( i −1)∗d+j − 1 ] ; }
m a t r i c e <T>& operator+=(const m a t r i c e <T>& M) ;
m a t r i c e <T>& operator−=(const m a t r i c e <T>& M) ;
m a t r i c e <T>& operator∗=( const T& s ) ;
m a t r i c e <T>& operator/=( const T& s ) ;
};
// o p e r a t i o n s a l g é b r i q u e s i n t e r n e s
template<typename T> m a t r i c e <T>& m a t r i c e <T> : : operator+=(const m a t r i c e <T>& M)
{
test_dim ( d , M. d , " o p e r a t o r ␣+=" ) ;
v e c t e u r <T>& v=static_cast<v e c t e u r <T>&>(∗t h i s ) ;
const v e c t e u r <T>& vM=static_cast<const v e c t e u r <T>&>(M) ;
v+=vM;
return ∗ t h i s ;
}
template<typename T> m a t r i c e <T>& m a t r i c e <T> : : operator−=(const m a t r i c e <T>& M)
{
test_dim ( d , M. d , " o p e r a t o r ␣−=" )
v e c t e u r <T>& v=static_cast<v e c t e u r <T>&>(∗t h i s ) ;
const v e c t e u r <T>& vM=static_cast<const v e c t e u r <T>&>(M) ;
v−=vM;
return ∗ t h i s ;
}
template<typename T> m a t r i c e <T>& m a t r i c e <T> : : operator∗=( const T& s )
{
v e c t e u r <T>& v=static_cast<v e c t e u r <T>&>(∗t h i s ) ;
v∗=s ;
return ∗ t h i s ;
}
template<typename T> m a t r i c e <T>& m a t r i c e <T> : : operator/=( const T& s )
{
i f ( s==0) s t o p ( " o p e r a t o r ␣/=␣ : ␣ d i v i s i o n ␣ par ␣ 0 " ) ;
v e c t e u r <T>& v=static_cast<v e c t e u r <T>&>(∗t h i s ) ;
v/=s ;
return ∗ t h i s ;
}

// o p e r a t i o n s a l g é b r i q u e s e x t e r n e s
template<typename T> m a t r i c e <T> operator+(const m a t r i c e <T>& M)
{ return M; }
template<typename T> m a t r i c e <T> operator −(const m a t r i c e <T>& M)
{ m a t r i c e <T> R=M; return R∗=−1; }
template<typename T> m a t r i c e <T> operator+(const m a t r i c e <T>& M1, const m a t r i c e <T>& M2)
{ m a t r i c e <T> R=M1; return R+=M2; }
template<typename T> m a t r i c e <T> operator −(const m a t r i c e <T>& M1, const m a t r i c e <T>& M2)
{ m a t r i c e <T> R=M1; return R−=M2; }
template<typename T> m a t r i c e <T> operator ∗ ( const m a t r i c e <T>& M, const T& s )
{ m a t r i c e <T> R=M; return R∗=s ; }
template<typename T> m a t r i c e <T> operator ∗ ( const T& s , const m a t r i c e <T>& M)
{ m a t r i c e <T> R=M; return R∗=s ; }
template<typename T> m a t r i c e <T> operator / ( const m a t r i c e <T>& M, const T& s )
{ m a t r i c e <T> R=M; return R/=s ; }

// p r o d u i t m a t r i c e −v e c t e u r
template<typename T>
v e c t e u r <T> operator ∗ ( const m a t r i c e <T>& M, const v e c t e u r <T>& u )
{
i n t d=M. d ;
test_dim ( d , u . dim ( ) , " p r o d u i t ␣ m a t r i c e −v e c t e u r " ) ;
v e c t e u r <T> Mu( d ) ;
f o r ( i n t i =1; i <=d ; i ++)
f o r ( i n t j =1; j<=d ; j ++) Mu( i )+=M( i , j ) ∗ u ( j ) ;
return Mu;
}
// o p é r a t e u r de f l u x
template<typename T>
ostr ea m & operator<<(os tr ea m& os , const m a t r i c e <T>& M)
{
i f (M. d<=0) { o s << " [ ] " ; return o s ; }
f o r ( i n t i =1; i <=M. d ; i ++)
{
o s << " | " ;
f o r ( i n t j =1; j <M. d ; j ++) o s << M( i , j ) << " ␣ " ;
o s << M( i ,M. d ) << " | " << e n d l ;

8
}
return o s ;
}

#endif

Ajout dans le fichier main.cpp :


// t e s t m a t r i c e
//============
c o u t << " \ nTest ␣ m a t r i c e \n " ;
i n t n=3;
m a t r i c e <double> M( n ) ;
f o r ( i n t i =1; i <=n ; i ++)
f o r ( i n t j =1; j<=n ; j ++) M( i , j )=10∗ i+j ;
c o u t << "M␣=␣ " << e n d l << M;
c o u t << "M+M␣=␣ " << e n d l << M+M;
c o u t << "M−M␣=␣ " << e n d l << M−M;
c o u t << " 2∗M␣=␣ " << e n d l << 2 . ∗M;
c o u t << "M/2 ␣=␣ " << e n d l << M/ 2 . ;
c o u t << "M∗V2␣=␣ " << M∗V2 << e n d l ;

Affichage du résultat :
Test matrice
M =
|11 12 13|
|21 22 23|
|31 32 33|
M+M =
|22 24 26|
|42 44 46|
|62 64 66|
M-M =
|0 0 0|
|0 0 0|
|0 0 0|
2*M =
|22 24 26|
|42 44 46|
|62 64 66|
M/2 =
|5.5 6 6.5|
|10.5 11 11.5|
|15.5 16 16.5|
M*V2 = (74,134,194)

Você também pode gostar