Problème pour dériver une classe

Signaler
Messages postés
32
Date d'inscription
mardi 15 janvier 2002
Statut
Membre
Dernière intervention
24 mars 2011
-
Messages postés
95
Date d'inscription
mercredi 5 décembre 2001
Statut
Membre
Dernière intervention
27 juin 2006
-
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
#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 "<>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");
*/
}

4 réponses

Messages postés
368
Date d'inscription
mercredi 14 novembre 2001
Statut
Membre
Dernière intervention
1 septembre 2008

Je t'avoue que je ne comprend pas ta source : ce n'est pas quelle n'est pas bien expliqué.
en clair, ce que tu fais, c'est que tu redefinie +
dans 5 + 3, c'est ca ?
Messages postés
40
Date d'inscription
lundi 17 décembre 2001
Statut
Membre
Dernière intervention
25 février 2004

Pourquoi ne pas essayer de définir un opérateur + dans ta classe Mat_Compr ?
Si tu redéfinis l'opérateur dans cette classe également, je pense qu'il n'y aura pas de problème.
Tiens moi au courant ...
Messages postés
32
Date d'inscription
mardi 15 janvier 2002
Statut
Membre
Dernière intervention
24 mars 2011

Voici les réponses aux 2 derniers messages
Messages postés
95
Date d'inscription
mercredi 5 décembre 2001
Statut
Membre
Dernière intervention
27 juin 2006

il faudrait definir dans la classe matrice compressé

const Mat_Compr &operator= (const Matrice &);

qui se chargerait de transformer l'objet matrice
renvoyer par l'operateur+ en un objet mat_compr
j'espere que ça va marcher, j'ai pas eu le temp de tester.
sinon il faudrait que tu t'habitue a te servir des references elle permettent d'economiser de l'espace ce qui est assez important pour des matrices qui peuvent etres de grandes taillesil faut aussi que tu definisse un operateurdans la classe matrice, car lorsque tu fait une copie de matrice a matrice (matrice1 matrice2) la copie ne se fait que superficielement et ton tableau dynamique n'est pas recopier, seul les pointeurs sont recopier, donc lorsque la matrice2 est detruite la matrice1 pointe dans le vide !!!
si tu veut plus de precision sur les objets envoi moi un mail
je te conseil un livre excellent sur les objet qui permettrai de resoudre tout tes problemes :
Algorithmique objet avec C++
de jean-pierre fournier au edition vuibert
c avec ça que j'ai appris a me servir correctement des objets