appel du destructeur et opérateurs - C++ - Programmation
Marsh Posté le 01-05-2008 à 10:45:27
Les appels au destructeur sont faits automatiquement à la disparition de l'objet...
Marsh Posté le 01-05-2008 à 10:45:34
in_your_phion a écrit :
est-ce bien comme ça qu'il faut faire ? e.g recopier les données de m dans l'instance qui est affecté par l'opérateur = ? |
Presque, là tu as au moins 2 raisons d'avoir des fuites mémoires.
Code :
|
après bon, les tableaux 1D ....
in_your_phion a écrit :
|
Oui et c'ets MAL
in_your_phion a écrit :
ca marche, sauf que il y a deux appel au destructeur après la ligne 3 et je ne sais pas d'ou ils sortent j'obtiens donc ceci : |
Montre moi le prototype de ton operateur *.
Je paries 50kg de carambar que tu passes tes operandes par copies et non par references.
Marsh Posté le 01-05-2008 à 10:46:36
ah tiens, j'avais mal compris la question, mais je comprends la réponse au moins .
Marsh Posté le 01-05-2008 à 11:21:11
Joel F a écrit : Je paries 50kg de carambar que tu passes tes operandes par copies et non par references. |
Le probleme ne serait-il pas plutot que l'operateur * renvoie un objet temporaire qui est detruit apres l'affectation?
Marsh Posté le 01-05-2008 à 12:46:38
ca expliquerait un appel au destructeur, le 2e viendrait d'où.
Anyway, je veut tout le code svp
Marsh Posté le 02-05-2008 à 00:44:07
Ace17 a écrit : Le probleme ne serait-il pas plutot que l'operateur * renvoie un objet temporaire qui est detruit apres l'affectation? |
salut tout le monde!
merci pour vos réponses effectivement je pense que le premier appel au destructeur se fait car (m1*m2) est stocqué dans un objet temporaire qui est détruit après que m3 l'ai copié. Par contre pour le deuxième j'en ai toujours aucune idée.
Merci Joel pour l'explication sur l'opérateur =. Voici l'opérateur * que j'ai implémenté :
Code :
|
j'ai bon ...?
(edit : est ce qu'on peut surcharger un opérateur () et ensuite l'utiliser dans un autre surcharge d'opérateur ? par exemple dans mon cas ce serai plus pratique de faire m(i,j) plutot que m[j +i*m.cols] mais ça a pas l'air de marcher, y'a til un moyen ?)
Marsh Posté le 02-05-2008 à 08:34:23
operator* est canoniquement implanté sous forme 'une fonction libre et non d'une fonction membre.
Ensuite ... OMG punaise les lignes 7-9, quelle horreur !
Au lieu de faire péter ton encapsulation en accédant aux membre de ton res, tu pourrais pas proprement définir un constructeur qui prends une paire de paramètre et alloue une matrix de cette taille ? ou bien une méthode resize ?
Alors maintenant question :
c'est pr l'école ou c'est pour un vrai projet ?
si c'est pr l'école, y a du boulot, peut tu me montrer TOUT ton code qu'on t'inculque quelques bonnes manières.
si c'est pour du boulot sérieux, arrête de réinventer la roue : Blitz++, NT2, boost::array au choix
sinon oui operartor() se surcharge sans probleme.
Marsh Posté le 02-05-2008 à 13:14:19
Un papier bien avec une exemple de multiplication de matrice efficace http://people.redhat.com/drepper/cpumemory.pdf §6.2
Déjà, si ton _data c'était un vector, t'aurais même pas à te poser la question d'operator=, etc
Marsh Posté le 02-05-2008 à 17:55:24
Joel F a écrit : operator* est canoniquement implanté sous forme 'une fonction libre et non d'une fonction membre. Ensuite ... OMG punaise les lignes 7-9, quelle horreur ! Alors maintenant question : sinon oui operartor() se surcharge sans probleme. |
salut,
merci pour vos réponses encore 1 fois En fait, ce n'est ni pour l'école ni pour un vrai projet de boulot ... c'est juste pour moi et apprendre le c++. Donc c'est pour ca que je ne fais pas de STL pour le moment, j'essaie de comprendre en partant de zéro, une fois que je me sentirai à l'aise je passerai à la stl
@Joel F
ok pour les lignes 7 à 9 ... en fait mon constructeur initialise la matrice avec un rand donc c'est pour ca que je l'ai pas appelé dans operator* ... dans ce cas c'est peut etre mon constructeur qui est foireux 'cf plus bas).
MAis sinon je comprends toujours pas pourquoi j'ai deux appels au destructeur ..
ps : pour operator(), je voulais savoir si je peux l'utiliser dans operator*
merki!
ps : voici TOUT mon code (dans le .h) :
Code :
|
ps : la ligne 82 me génère l'erreur suivante :
|
ce serait pas plutot
Code :
|
?
Marsh Posté le 02-05-2008 à 19:43:21
je réponds plus tant que tu arretera pas d'utiliser char* et T* au lieu de string et de vector<T>.
Ca sert à rien d'attendre pour utiliser la STL à part se faire chier
Marsh Posté le 03-05-2008 à 02:11:21
Joel F a écrit : je réponds plus tant que tu arretera pas d'utiliser char* et T* au lieu de string et de vector<T>. |
ouaiiii ...bon ....
que penses tu de ma brand new version tunée avec la STL alors ????
Code :
|
ça envoie ...?
Marsh Posté le 04-05-2008 à 10:01:55
ReplyMarsh Posté le 04-05-2008 à 10:23:11
et je maintiens que * est canoniquement une fonction libre qui utilise la fonction membre +=
Marsh Posté le 04-05-2008 à 20:10:11
Joel F a écrit : et je maintiens que * est canoniquement une fonction libre qui utilise la fonction membre += |
bah je suis d'accord avec ça mais:
- y a quoi comme papier pour vraiment appuyer ça ? vu que les deux sont légaux, à part le poids des arguments techniques (operator ? est une opération externe, c'est meilleur d'implémenter operator ? à partir de operator ?=), j'arrive pas à trouver une vraie recommandation là dessus (style goto considered harmful).
- imagine que tu implémentes une classe Matrice 2D *=(const Matrice& ) ça n'a pas trop de sens. Alors du coup tu implémentes * en fonction libre, mais là tu te retrouves peut-être à devoir mettre un friend.
Parce qu'au final on a pas réussi à convaincre i_p_h a changer son implémentation. Mauvais arguments ?
Marsh Posté le 04-05-2008 à 20:38:42
pour le papier j'en cherche encore. Si j'en trouve pas j'en ecrirais un
sinon, en quoi *= n'a pas de sens ?
Marsh Posté le 04-05-2008 à 20:55:29
Pour une matrice, bah oui ça peut, mais ça change pas mal la tronche de matrice, tu ne peux pas faire la multiplication sur place
Marsh Posté le 04-05-2008 à 21:56:37
Certes, je sais plus comment j'ai contourner le probleme dans NT2
Marsh Posté le 04-05-2008 à 22:03:18
Ouais enfin bon, tu vois le dilemne operator?= / operator? / friend / etc
Marsh Posté le 04-05-2008 à 22:08:29
bref tu vois quoi comme forme canonique quand operator?= ne s'implémente en fait qu'en utilisant operator? ?
Marsh Posté le 04-05-2008 à 23:07:24
enumerons les cas :
* operator(X) s'ecrit comme appel à operator(+)=
* operator(X)= s'ecrit comme appel à operator(+)
* operator(X)= et operator(X) ont rien à voir entre eux
En gros ?
Marsh Posté le 05-05-2008 à 10:13:59
bah voila en gros :
si il y a "dependance" des appels entre (X)= et (X) tu écris l'une en fonction de l'autre de manière naturelle.
Dans le cas ou les deux sont décorrellés, bah à part dupliquer du code je vois pas ce que tu peut faire.
L'argument de dire (X) s'écrit en appelant (X)= reste celui là : réduire la code duplication
Marsh Posté le 05-05-2008 à 14:59:37
nan mais ça je sais bien. Mais si tu dois écrire operator?= en fonction de operator?, bah il ne vaudrait alors pas mieux mettre operator?= en fonction membre plutôt qu'en friend libre ?
Marsh Posté le 05-05-2008 à 22:28:15
Taz a écrit : Si tu veux persister dans cette voie là, il manque des tas de const. |
ah ? où est ce que je devrais mettre des const ? sinon, c'est la bonne méthode ou pas ?
merci
Marsh Posté le 07-05-2008 à 23:28:14
Taz a écrit : ton operator+ par exemple |
salut,
je vois pas ... il manque un const dans operator+ ? ou ca ??
Marsh Posté le 08-05-2008 à 08:27:33
Matrix operator+(const Matrix & m) const
tout simplement.
Une méthode qui ne modifie pas l'état d'un objet est par def. const.
Marsh Posté le 08-05-2008 à 20:21:20
j'ai pas tout lu, mais :
if(_data) delete[] _data;
beurk !
delete fait lui-même la vérif du pointeur NULL, ici c'est redondant et useless. C'est valable aussi pour free() en C.
Marsh Posté le 08-05-2008 à 20:28:30
c'est pas prévu par le standard. gcc le fait mais pas VC++ (ou l'inverse)
Marsh Posté le 08-05-2008 à 20:50:57
euh, il me semble que si, la verif de delete et delete[] le fait en standard. Je vais aller vérifier ça, et j'espère ne pas me tromper car je fais des delete NULL assez souvent.
Marsh Posté le 08-05-2008 à 20:54:04
http://www.cplusplus.com/doc/tutorial/dynamic.html
argument to delete must be either a pointer to a memory block previously allocated with new, or a null pointer (in the case of a null pointer, delete produces no effect).
Marsh Posté le 08-05-2008 à 20:55:37
et même chez microsoft :
Using delete on a pointer to an object not allocated with new gives unpredictable results. You can, however, use delete on a pointer with the value 0.
http://msdn.microsoft.com/en-us/li [...] S.80).aspx
Marsh Posté le 08-05-2008 à 21:02:51
ah ok ^^ c'est le delete d'un unallocated pointer qui chouine, OK c'est noté
Marsh Posté le 08-05-2008 à 21:11:19
ah oui, c'est sûr que :
int* t;
delete t;
ça marche pas trop. D'ailleurs j'espère qu'aucun compilo n'accepte ça. Par contre comme sous windows noyau NT (et +) la mémoire est initialisée avec des 0, ça marche en pratique. Mais pas sous Windows noyau 95 (jusqu'à Me).
D'où le fait que perso, qd je code sous Win, je teste toujours en parallèle sous un vieux Win98. Et en même temps ça teste le respect de qlq limites historiques du noyau Win32 (pas de HBITMAP > 16Mo, pas de LABEL > 64Ko, tout ça...).
Marsh Posté le 10-05-2008 à 02:52:28
Joel F a écrit : Matrix operator+(const Matrix & m) const tout simplement. |
ok merci pour vos réponses. Puisqu'on parle de la STL, j'ai une petite autre question siouplé...
j'aimerai savoir si c'est la bonne manière de déclarer un tableau 2D de vector avec la stl. Et surtout, est ce que ca a du sens de déclarer un pointeur vers un vecteur, car dans mon exemple c'est pas un pointeur mais je sais pas comment faire si c'est un pointeur. Voila l'exemple :
Code :
|
|
je voudrais savoir si ca a du sens de faire :
Code :
|
?
si oui comment je peux initialiser ce pointeur ...
merci d'avance
Marsh Posté le 10-05-2008 à 08:56:25
vector<vector<int> > suffit, mais c'est inefficace, mattes du coté de boost::multi_array
Marsh Posté le 10-05-2008 à 10:05:23
Code :
|
Ton constructeur, mais en 3 lignes.
Pour un tableau (X x Y) rempli avec des 2. Et en C++ on ne remplit pas avec des boucles for, on utilise std::fill ou std::fill_n.
Pour du dimention 2, il y a aussi les std::valarray, ça a peut-être déjà été dit.
Marsh Posté le 10-05-2008 à 17:08:12
jesus_christ a écrit :
|
ok merci pour le constructeur ...
valarray je connaissais pas, je ne vois pas de documentation sur cpp.com ou sgi http://www.cplusplus.com/query/search.cgi?q=valarray
...
Marsh Posté le 10-05-2008 à 20:18:32
un petit exemple là, mais valarray est peu documenté et assez dur à utiliser, mais les implémentations sont très performantes.
http://www.josuttis.com/libbook/num/gslice1.cpp.html
Marsh Posté le 30-04-2008 à 23:16:19
Bonjour,
je suis en train de faire des petites fonctions d'opérations basiques sur les matrices en c++.
en gros j'ai une classe Matrix, et pour l'instant je me contente de faire de la surcharge d'opérateurs : +, =, *
j'aurais deux petites questions siouplait...
1) j'ai fait un opérateur d'affectation = :
est-ce bien comme ça qu'il faut faire ? e.g recopier les données de m dans l'instance qui est affecté par l'opérateur = ? Que se passe t'il si on redéfini pas =, c'est juste une copie membre à membre ? cad :
?
2) Autrement j'ai une deuxième question ... là je comprend pas du tout... J'ai donc fait mes opérateurs et j'ai testé ça dans mon main :
ca marche, sauf que il y a deux appel au destructeur après la ligne 3 et je ne sais pas d'ou ils sortent
j'obtiens donc ceci :
affichage de la matrice m1 ..
affichage de la matrice m2 ..
appel du constructeur de recopie
appel du destructeur
appel du destructeur
pourquoi ces appels au destructeur ..??
merci par avance..
Message édité par in_your_phion le 30-04-2008 à 23:16:46