Operator et pointeur [C++]
Résolu/Fermé
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
-
3 mai 2004 à 17:31
Benur29 - 26 janv. 2007 à 15:14
Benur29 - 26 janv. 2007 à 15:14
A voir également:
- Operator et pointeur [C++]
- Pointeur souris - Guide
- Pointeur souris disparu windows 10 - Guide
- Pointeur souris disparu pc portable asus - Guide
- Pointeur satellite astra gratuit - Forum TNT / Satellite / Réception
- Pointeur satellite fransat ✓ - Forum TNT / Satellite / Réception
9 réponses
blurk
Messages postés
486
Date d'inscription
vendredi 16 avril 2004
Statut
Membre
Dernière intervention
15 mars 2009
160
4 mai 2004 à 09:04
4 mai 2004 à 09:04
dans le constructeur de matrix, tu peux mettre un new, il y a même
moyen( de passer un paramètre pour la taille d'allocation lors de la déclaration d'une instance de matrix.
matrix(1) *a; avec un new dedans. (1 à multiplier par sizeof de matrix dans le constructeur)
et dans le destructeur le delete[]
Les constructeurs par défaut servent surtout à ça.
autrement, je sais qu'il n'est pas interdit de faire de l'allocation statique:
Matrix& operator*(matrix A[2], Matrix B[2] );
le compilateur se débrouille tout seul pour l'allocation.
Je sais pas si c'est la solution, mais il y a sûrement encore d'autres moyens.
a+
moyen( de passer un paramètre pour la taille d'allocation lors de la déclaration d'une instance de matrix.
matrix(1) *a; avec un new dedans. (1 à multiplier par sizeof de matrix dans le constructeur)
et dans le destructeur le delete[]
Les constructeurs par défaut servent surtout à ça.
autrement, je sais qu'il n'est pas interdit de faire de l'allocation statique:
Matrix& operator*(matrix A[2], Matrix B[2] );
le compilateur se débrouille tout seul pour l'allocation.
Je sais pas si c'est la solution, mais il y a sûrement encore d'autres moyens.
a+
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
4 mai 2004 à 09:48
4 mai 2004 à 09:48
Merci de ta réponse blurk. Je n'ai pas tout compris surtout car j'ai toujours essayer d'éviter les new et delete. Je ne sais pas très bien comment ils fonctionnent... Je vais me renseigner.
en fait pour l'opérateur, les "&" dans l'apel, si je ne les met pas, j'ai des erreurs de calcul : le passage par valeur se fait rès mal. En plus il me parait un peu restrictif de donnée une taille de matrice dans l'appel "matrix A[2]" si je fait une matrice plus grande, je fait comment?
Salutation !
Char Snipeur
en fait pour l'opérateur, les "&" dans l'apel, si je ne les met pas, j'ai des erreurs de calcul : le passage par valeur se fait rès mal. En plus il me parait un peu restrictif de donnée une taille de matrice dans l'appel "matrix A[2]" si je fait une matrice plus grande, je fait comment?
Salutation !
Char Snipeur
Matrix& operator*(matrix& A, Matrix& B)
l'opérateur * doit retourner *this et pas un objet temporaire alloué !
l'opérateur * doit retourner *this et pas un objet temporaire alloué !
Je reviens après 10 cafés, ça va mieux
Conventions classiques C++
- l'opérateur * rend Matrice
- l'opérateur *= rend une Matrice*
-ils prennent tous les 2 un seul paramètre
donc
Matrice& operator*=(matrix& b)
{
return *this = *this * b; // ici il FAUT que l'opérateur = existe ET on se sert de l'opérateur * écrit ci dessous
}
Matrice operator*(matrix& b) {
Matrice c(this->getNbLigs(), this->getNbCols());
//remplissage de c
return c; // ici il FAUT que le constrcuteur de copie existe
}
tu dois définir aussi
Matrice& operator=(matrix& b) { // opérateur d'affetatiion
// ...
}
Matrice(matrix& b) { // constrcuteru de copie
// ...
}
est-ce clair ?
marvinrouge
Conventions classiques C++
- l'opérateur * rend Matrice
- l'opérateur *= rend une Matrice*
-ils prennent tous les 2 un seul paramètre
donc
Matrice& operator*=(matrix& b)
{
return *this = *this * b; // ici il FAUT que l'opérateur = existe ET on se sert de l'opérateur * écrit ci dessous
}
Matrice operator*(matrix& b) {
Matrice c(this->getNbLigs(), this->getNbCols());
//remplissage de c
return c; // ici il FAUT que le constrcuteur de copie existe
}
tu dois définir aussi
Matrice& operator=(matrix& b) { // opérateur d'affetatiion
// ...
}
Matrice(matrix& b) { // constrcuteru de copie
// ...
}
est-ce clair ?
marvinrouge
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Bien que la discussion soit terminée depuis belle lurette, je la complète pour éclairer d'autres esprits
si on déclare ainsi alors on doit retourner *this :
Matrice& operator*=(matrix& b)
{
return *this = *this * b; // ici il FAUT que l'opérateur = existe ET on se sert de l'opérateur * écrit ci dessous
}
par contre si on déclare de la façon qui suit, on peut retourner une valeur construite dans la fonction membre :
Matrice& operator*=(matrix& b) const
{
Matrice* resultat = new Matrice(param_d-init-du_constructeur);
.....
return *resultat
}
En espérant vous éclairer
si on déclare ainsi alors on doit retourner *this :
Matrice& operator*=(matrix& b)
{
return *this = *this * b; // ici il FAUT que l'opérateur = existe ET on se sert de l'opérateur * écrit ci dessous
}
par contre si on déclare de la façon qui suit, on peut retourner une valeur construite dans la fonction membre :
Matrice& operator*=(matrix& b) const
{
Matrice* resultat = new Matrice(param_d-init-du_constructeur);
.....
return *resultat
}
En espérant vous éclairer
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
25 janv. 2007 à 08:54
25 janv. 2007 à 08:54
Salut.
Après des tests, et vue que j'ai apris un peu mieux le C++.
Le mieux est d'utiliser :
Matrix operator*(Matrix& A, Matrix& B);
cette fonction est défini en dehors de la class, c'est une surcharge de l'opérateur binaire '*'
J'ai enlever le '&' dans le retour de la fonction, car c'est la valeur qui nous intéresse, il n'y a aucune utilité de modifier A*B (A*B=6 n'a pas de sens en affectation) J'ai mis des '&' dans les paramètres de la fonctions pour passer les références des objets, car cela évite les erreurs de recopie et gagne du temps de recopiage des objets.
daccord sur la fonction membre 'operator*=' elle est parfaite.
en revanche la fonction 'matrix& operator*(matrix& b)' génère toujours des fuites de mémoire car la matrice resultat n'est jamais détruite. Dans ce cas, il est possible (3 matrice A,B et C) de faire :
A*B=C, resultat prend la valeur de C par l'opérateur '=' mais A et B ne sont pas modifier. et à chaque fois que tu fera A*B tu créra une nouvelle variable resultat .
Après des tests, et vue que j'ai apris un peu mieux le C++.
Le mieux est d'utiliser :
Matrix operator*(Matrix& A, Matrix& B);
cette fonction est défini en dehors de la class, c'est une surcharge de l'opérateur binaire '*'
J'ai enlever le '&' dans le retour de la fonction, car c'est la valeur qui nous intéresse, il n'y a aucune utilité de modifier A*B (A*B=6 n'a pas de sens en affectation) J'ai mis des '&' dans les paramètres de la fonctions pour passer les références des objets, car cela évite les erreurs de recopie et gagne du temps de recopiage des objets.
daccord sur la fonction membre 'operator*=' elle est parfaite.
en revanche la fonction 'matrix& operator*(matrix& b)' génère toujours des fuites de mémoire car la matrice resultat n'est jamais détruite. Dans ce cas, il est possible (3 matrice A,B et C) de faire :
A*B=C, resultat prend la valeur de C par l'opérateur '=' mais A et B ne sont pas modifier. et à chaque fois que tu fera A*B tu créra une nouvelle variable resultat .
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
26 janv. 2007 à 09:31
26 janv. 2007 à 09:31
Je maintient, ta solution n'es pas bonne car elle engendre une fuite de mémoire, et aussi pour les raisons exposés dans le messsage précédent.
mamiemando
Messages postés
33079
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
23 avril 2024
7 749
26 janv. 2007 à 10:14
26 janv. 2007 à 10:14
Tout à fait d'accord avec charsniper mais en fait c'est presque bon :
En fait si tu calcule A*B tu es effectivement de créer une matrice C=A*B et donc de l'allouer (car tu ne veux modifier ni A, ni B). Cependant qui dit new dit delete, et ici le delete n'était jamais fait (donc la mémoire occupée par C jamais rendue).
Ici tu ne peux pas retourner une référence, ça n'a pas de sens. Retourner une référence n'a de sens que si c'est une variable qui est déjà créée. Typiquement quand tu passes une variable en paramètre, on passe en générale la référence car ça évite de recopier dans la pile la variable passée en paramètre. Ici tu es de toutes façons condamné à créer une nouvelle variable de retour C donc... on la retourne directement :)
Au niveau allocation c'est mieux, car la variable de retour sera déclarée sans new et sera donc automatiquement détruite à la fin du scope ou elle est déclarée :
Bonne chance
matrix operator*(matrix& b)const { matrix result(.......); //... return result }
En fait si tu calcule A*B tu es effectivement de créer une matrice C=A*B et donc de l'allouer (car tu ne veux modifier ni A, ni B). Cependant qui dit new dit delete, et ici le delete n'était jamais fait (donc la mémoire occupée par C jamais rendue).
Ici tu ne peux pas retourner une référence, ça n'a pas de sens. Retourner une référence n'a de sens que si c'est une variable qui est déjà créée. Typiquement quand tu passes une variable en paramètre, on passe en générale la référence car ça évite de recopier dans la pile la variable passée en paramètre. Ici tu es de toutes façons condamné à créer une nouvelle variable de retour C donc... on la retourne directement :)
Au niveau allocation c'est mieux, car la variable de retour sera déclarée sans new et sera donc automatiquement détruite à la fin du scope ou elle est déclarée :
matrix A,B; //Initialisation de A et B //... // Calcul de C = A*B { int x=69; matrix C = A*B; //... } // C est détruite en arrivant à cette accolade au même titre que x
Bonne chance
ok ; autant pour moi
En ce ki concerne tes fuites memoire : je suppose que tu utilises des tableaux intermédiaires.
si tu les alloues dynamiquement : n'oublie pas de les détruire proprement :
int* tab = new int[n];
....
delete[] tab;
int** tab = new int*[n1]; //tab[n1][n2]
for(int j= 0; j<n1 ; j++)
{
tab[j] = new int[n2];
for(int h=0; h<n2 ; h++)
{
tab[j][h] = .........;
}
}
......
for(j= 0; j<n1 ; j++)
{
delete[] tab[j];
}
delete[] tab;
avec ça c propre
En ce ki concerne tes fuites memoire : je suppose que tu utilises des tableaux intermédiaires.
si tu les alloues dynamiquement : n'oublie pas de les détruire proprement :
int* tab = new int[n];
....
delete[] tab;
int** tab = new int*[n1]; //tab[n1][n2]
for(int j= 0; j<n1 ; j++)
{
tab[j] = new int[n2];
for(int h=0; h<n2 ; h++)
{
tab[j][h] = .........;
}
}
......
for(j= 0; j<n1 ; j++)
{
delete[] tab[j];
}
delete[] tab;
avec ça c propre