J'ai créé une classe Matrice comportant des fonctions get_ele, set_ele (toutes les 2 sont "virtual") et la redéfinition de l'opérateur +.
Dans ma classe hérité Mat_Compr, je redéfinis le get_ele et le set_ele.
Le prototype de la redéfinition du + est :
friend Matrice operator+(Matrice mat1, Matrice mat2);
Comment faire pour que, lorsqu'on utilise l'opérateur + avec des objets Mat_Compr, l'objet utilisé pour l'addition qui est renvoyé comme résultat de l'opération sois un objet de type Mat_Compr.
Voici la redéfinition de l'opérateur + :
Matrice operator+(Matrice mat1, Matrice mat2)
{
int L1, C1, L2, C2, i, j;
// L : nombre de ligne
// C : nombre de colonne
L1=mat1.get_M_L();
C1=mat1.get_M_C();
L2=mat2.get_M_L();
C2=mat2.get_M_C();
// crée un objet matrice vide
// il faudrait un objet Mat_Compr quand on utilise l'opérateur+ avec des objet Mat_Compr
Matrice temp(0,L1,C1);
if ((L1==L2) && (C1==C2))
{
for (i=0;i<L1;i++)
for (j=0;j<C1;j++)
temp.Set_ele(i,j,(mat1.Get_ele(i,j)+mat2.Get_ele(i,j)));
return temp;
}
else
{
cout<<"Calcul impossible"<<endl;
return temp;
}
}
Merci
Pour les personnes qui seraient interessé voici le code source complet :
#include <fstream.h>
#include <iostream.h>
#include <stdlib.h>
/* ------------------ CLASSE MATRICE ---------------------*/
class Matrice
{
public:
// constructeur manuelle et par fichier
Matrice(int manuelle, int _M_L, int _M_C);
Matrice(char *Nom_Fichier,int _M_L,int _M_C);
// destructeur
~Matrice();
// renvoi le nombre de ligne et de colonne
int get_M_L(){return (M_L);}
int get_M_C(){return (M_C);}
// fonction identique renvoyant l'element i j de la matrice
int get_el(int i, int j){return Mat[i][j];}
virtual int Get_ele(int i,int j){return Mat[i][j];}
virtual void Set_ele(int i,int j,int V){Mat[i][j]=V;}
// redefinition des operateur
friend Matrice operator+(Matrice mat1, Matrice mat2);
friend Matrice operator-(Matrice mat1, Matrice mat2);
friend Matrice operator*(Matrice mat1, Matrice mat2);
void Transpose();
// affichage de la matrice
void Affiche();
private:
int **Mat;
int M_L;
int M_C;
};
/* ------------------ CONSTRUCTEUR ------------------ */
// constructeur manuelle si manuelle = 1, sinon crée de l'espace pour la matrice
// mais la laisse vide
Matrice::Matrice(int manuelle, int _M_L,int _M_C):M_L(_M_L),M_C(_M_C)
{
int i;
int j;
// crée de l'espace pour M_C pointeur d'entier
Mat=new int *[M_L];
// remplit la matrice
for(i=0;i<M_L;i++)
Mat[i]=new int[M_C];
if (manuelle==1)
{
for(i=0;i<M_L;i++)
{
for(j=0;j<M_C;j++)
{
cout<<"Entrer la valeur "<<i+1<<" "<<j+1<<" : ";
cin>>Mat[i][j];
}
cout<<endl;
}
}
}
// constructeur par fichier
Matrice::Matrice(char *Nom_Fichier,int _M_L,int _M_C):M_L(_M_L),M_C(_M_C)
{
int i;
int j;
// crée de l'espace pour M_C pointeur d'entier
Mat=new int *[M_L];
// remplit la matrice
for(i=0;i<M_L;i++)
Mat[i]=new int[M_C];
ifstream f(Nom_Fichier);
for(i=0;i<M_L;i++)
{
for(j=0;j<M_C;j++)
{
f>>Mat[i][j];
}
}
f.close();
}
/* ---------------- DESTRUCTEUR --------------- */
Matrice::~Matrice()
{
delete Mat;
}
/* ---------------- operation ---------------- */
Matrice operator+(Matrice mat1, Matrice mat2)
{
int L1, C1, L2, C2, i, j;
L1=mat1.get_M_L();
C1=mat1.get_M_C();
L2=mat2.get_M_L();
C2=mat2.get_M_C();
// crée un objet matrice vide
Matrice temp(0,L1,C1);
if ((L1==L2) && (C1==C2))
{
for (i=0;i<L1;i++)
for (j=0;j<C1;j++)
temp.Set_ele(i,j,(mat1.Get_ele(i,j)+mat2.Get_ele(i,j)));
return temp;
}
else
{
cout<<"Calcul impossible"<<endl;
return temp;
}
}
Matrice operator-(Matrice mat1, Matrice mat2)
{
int L1, C1, L2, C2, i, j;
L1=mat1.get_M_L();
C1=mat1.get_M_C();
L2=mat2.get_M_L();
C2=mat2.get_M_C();
// crée un objet matrice vide
Matrice temp(0,L1,C1);
if ((L1==L2) && (C1==C2))
{
for (i=0;i<L1;i++)
for (j=0;j<C1;j++)
temp.Set_ele(i,j,(mat1.Get_ele(i,j)-mat2.Get_ele(i,j)));
return temp;
}
else
{
cout<<"Calcul impossible"<<endl;
return temp;
}
}
Matrice operator*(Matrice mat1, Matrice mat2)
{
int L1, C1, L2, C2, i, j, k;
L1=mat1.get_M_L();
C1=mat1.get_M_C();
L2=mat2.get_M_L();
C2=mat2.get_M_C();
// crée un objet matrice vide
Matrice temp(0,L1,C2);
if (C1==L2)
{
for (i=0;i<L1;i++)
for (j=0;j<C2;j++)
for (k=0;k<C2;k++)
temp.Set_ele(i,j,(temp.Get_ele(i,j)+mat1.Get_ele(i,k)*mat2.Get_ele(k,j)));
return temp;
}
else
{
cout<<"Calcul impossible"<<endl;
return temp;
}
}
/* ----------------- transpose ----------------- */
void Matrice::Transpose()
{
int L, C, i, j;
L=M_L;
C=M_C;
Matrice temp(0,L,C);
for (i=0;i<L;i++)
for (j=0;j<C;j++)
temp.Set_ele(i,j,Get_ele(j,i));
for (i=0;i<L;i++)
for (j=0;j<C;j++)
Set_ele(i,j,temp.Get_ele(i,j));
// delete temp;
}
/* ----------------- affichage ----------------- */
void Matrice::Affiche()
{
int L=get_M_L();
int C=get_M_C();
for(int i=0;i<L;i++)
{
cout<<endl;
for(int j=0;j<C;j++)
{
cout<<Get_ele(i,j)<<"\t\t";
}
}
}
/* ------------------- CLASS MATRICE COMPRESSE ----------------------- */
class Mat_Compr:public Matrice
{
private:
int *mat_comp; // pointeur sur la matrice compresse
int taille;
public:
// compresse la matrice
Mat_Compr(int manuelle, int _M_L,int _M_C);
// destructeur
~Mat_Compr();
// recupere l'elt i j de la matrice
int Get_ele(int i,int j);
// ecrase la valeur i j
void Set_ele(int i,int j,int V);
// renvoie le taux de compression
double Taux(){return (taille/(get_M_L()*get_M_C()*sizeof(int)));}
};
/* ------------------ constructeur ------------------- */
// construit la matrice compréssé
Mat_Compr::Mat_Compr(int _manuelle, int _M_L, int _M_C):Matrice(_manuelle, _M_L, _M_C)
{
int i,j;
// L et C sont le nombre de ligne et de colonne, récupérés de la classe mère
int L=get_M_L();
int C=get_M_C();
// compteur de nombre différent de zero par ligne
int nb;
// tableau provisoir, en attendant de connaitre la taille de la matrice compressé
int *tab;
// p est un pointeur sur le tab provisoire, pour le remplir case par case
int *p;
tab=new int[2*L*C+L]; // le max de case que l'on puisse avoir, pour le tableau provisoir
p=tab;
for (i=0;i<L;i++)
{
nb=0;
// On regarde combien il y a d'element non nul sur la ligne i
for (j=0;j<C;j++)
{
if(get_el(i,j) != 0)
nb++;
}
// on inscrit ce nombre
*p=nb;
// passe à la case suivante du tableau
p++;
// ecrit le numero de colonne puis la valeur
for (j=0;j<C;j++)
{
if(get_el(i,j) != 0)
{
// on indique le num de colonne
*p=j;
p++;
// on indique la valeur de la variable
*p=get_el(i,j);
p++;
}
}// fin for Colonne
}// fin for Ligne
// on calcul la taille de la matrice compressé en faisant une soustraction des adresses des pointeurs
taille=p-tab;
// on cree dynamiquement cette matrice
mat_comp=new int[taille];
// on recopie le tableau dans la matrice compressé
for(i=0;i<taille;i++)
{
mat_comp[i]=tab[i];
}
delete tab;
}
/* ------------------- destructeur --------------------- */
Mat_Compr::~Mat_Compr()
{
delete mat_comp;
}
/* ------------------- get ---------------- */
int Mat_Compr::Get_ele(int i, int j)
{
int x;
int L=get_M_L();
int C=get_M_C();
int *p;
p=mat_comp;
// on vas sauter le bon nombre de case pour se placer au début de la ieme ligne
// /!\ L remplacer par i
for (x=0;x<i;x++)
{
p+=((*p)*2+1);
}
// on récupère le nombre d'element qui correspondront a la ligne i dans la matrice compresse
int nb=*p;
// on passe aux colones maintenant
p++;
// on vas chercher la colonne j
for(x=0;x<nb*2;x+=2) // on saute 2 cases à la fois
{
if(*p==j)
{
p++;
return(*p);
}
else
p+=2;
}
return 0; // si on a pas trouve notre colonne, c'est qu'elle contenait un zero.
}
/* --------------------- set ---------------------- */
void Mat_Compr::Set_ele(int i, int j, int V)
{
int x;
// Le premier pointeur, pour trouver l'emplacement
int *p;
p=mat_comp;
// on vas sauter le bon nombre de case pour se placer au début de la ieme ligne
// /!\ L remplacer par i
for (x=0;x<i;x++)
p+=((*p)*2+1);
// On test si il y avait un nombre nul dans cette case
if(Get_ele(i,j)==0)
{
if(V!=0) // si l'element a jouter est diff de zero, on l'ajoute, sinon, on ne fait rien
{
// La matrice temporaire, avec le nouveau resultat
int *mat_temp;
mat_temp=new int[taille+2];
// Le second pointeur pour la copie
int *q;
q=mat_comp;
// Le troisieme pointeur pour la matrice temporaire mat_Temp
int *r;
r=mat_temp;
// On recopie le début du tableau
while(q<p)
{
*r=*q;
r++;
q++;
}
// Dans la case du nombre de colone par ligne non NUL, on agrément de 1
*r=*q+1;
// Dans la case suivante, on précise le num de colone
r++;
*r=j;
// puis la valeur de ce cette colonne
r++;
*r=V;
// ensuite, on recopie le reste du tableau, jusqu'à la fin
r++; q++;
while(q<(mat_comp+(taille)))
{
*r=*q;
r++;
q++;
}
// on inverse les tableaux
int *t;
t=mat_comp;
mat_comp=mat_temp;
mat_temp=t;
delete mat_temp;
}
}
else // if(Get_ele(i,j)!=0)
{
if(V==0) // si l'element a jouter vaut zero, il faut effacer la case correspondante
{
// La matrice temporaire, avec le nouveau resultat
int *mat_temp;
mat_temp=new int[taille-2];
// Le second pointeur pour la copie
int *q;
q=mat_comp;
// Le troisieme pointeur pour la matrice temporaire mat_Temp
int *r;
r=mat_temp;
// On recopie le début du tableau
while(q<p)
{
*r=*q;
r++;
q++;
}
// Dans la case du nombre de colone par ligne non NUL, on décrément de 1
*r=*q-1;
q++;
r++;
p++;
// on place le premier pointeur à la colonne à effacer
while(*p!=j)
p+=2;
// ensuite, on copie jusque là
while(q<p)
{
*r=*q;
r++;
q++;
}
q+=2;
// enfin, on copie le reste du tableau
while(q<(mat_comp+(taille)))
{
*r=*q;
r++;
q++;
}
// on change le nombre de ligne et colonne
// on inverse les tableaux
int *t;
t=mat_comp;
mat_comp=mat_temp;
mat_temp=t;
delete mat_temp;
}
else // if(V!=0)
{
// on récupère le nombre d'element qui correspondront a la ligne i dans la matrice compresse
int nb=*p;
// on passe aux colones maintenant
p++;
// on vas chercher la colonne j
for(x=0;x<nb*2;x+=2) // on saute 2 cases à la fois
{
if(*p==j)
{
// Quand on a trouvé la bonne, dans la case suivante, on change la valeur.
p++;
*p=V;
}
else
// sinon, on ragarde la prochaine colonne
p+=2;
}
}// else
}// else
}
/* ----------------- main -------------------- */
void main()
{
Matrice Mat_1("matrice.txt",3,3);
Mat_1.Affiche();
cout<<endl;
system("PAUSE");
Matrice Mat_2("matrice.txt",3,3);
Mat_2.Affiche();
cout<<endl;
system("PAUSE");
Mat_1=Mat_1+Mat_2;
Mat_1.Affiche();
cout<<endl;
system("PAUSE");
Mat_1=Mat_1-Mat_2;
Mat_1.Affiche();
cout<<endl;
system("PAUSE");
Mat_1=Mat_1*Mat_2;
Mat_1.Affiche();
cout<<endl;
system("PAUSE");
Mat_1.Transpose();
Mat_1.Affiche();
cout<<endl;
system("PAUSE");
/*
Mat_Compr Mat_3(1,2,2);
Mat_3.Affiche();
cout<<endl;
system("PAUSE");
Mat_Compr Mat_4(1,2,2);
Mat_4.Affiche();
cout<<endl;
system("PAUSE");
Mat_3=Mat_3+Mat_4;
Mat_3.Affiche();
cout<<endl;
system("PAUSE");
*/
}