Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
4534 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  appel du destructeur et opérateurs

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

appel du destructeur et opérateurs

n°1727126
in_your_ph​ion
Posté le 30-04-2008 à 23:16:19  profilanswer
 

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 = :

 
Code :
  1. Matrix & operator=(const Matrix  & m) {
  2.  _cols = m._cols; //le nombre de colonnes
  3.  _rows = m._rows; //le nombre de lignes
  4.  _data = new double [_cols*_rows]; //les données dans un tablo 1d
  5.  memcpy(_data, m._data, sizeof(double)*_cols*_rows );
  6.  return (*this) ;
  7. }
 

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 :

 
Code :
  1. _cols=m._cols;
  2. _rows=m._rows;
  3. data=m->data;
 

?

 

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 :

 
Code :
  1. Matrix m1(2,3) , m2(3,3), m3; //les matrices avec leurs tailles
  2. m1.display(); //affiche
  3. m2.display();
  4. m3 = m1*m2; // ligne 3
  5. //...
  6. //d'autres opérations à caractère très très intéressant ...
 

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 cité 1 fois
Message édité par in_your_phion le 30-04-2008 à 23:16:46
mood
Publicité
Posté le 30-04-2008 à 23:16:19  profilanswer
 

n°1727167
skeye
Posté le 01-05-2008 à 10:45:27  profilanswer
 

Les appels au destructeur sont faits automatiquement à la disparition de l'objet...


---------------
Can't buy what I want because it's free -
n°1727168
Joel F
Real men use unique_ptr
Posté le 01-05-2008 à 10:45:34  profilanswer
 

in_your_phion a écrit :


1) j'ai fait un opérateur d'affectation = :

 
Code :
  1. Matrix & operator=(const Matrix  & m) {
  2.  _cols = m._cols; //le nombre de colonnes
  3.  _rows = m._rows; //le nombre de lignes
  4.  _data = new double [_cols*_rows]; //les données dans un tablo 1d
  5.  memcpy(_data, m._data, sizeof(double)*_cols*_rows );
  6.  return (*this) ;
  7. }
 

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 :
  1. Matrix & operator=(const Matrix  & m)
  2. {
  3.   if(m != *this)
  4. {
  5.    _cols = m._cols; //le nombre de colonnes
  6.    _rows = m._rows; //le nombre de lignes
  7.  
  8.    if(_data) delete[] _data;
  9.    _data = new double [_cols*_rows]; //les données dans un tablo 1d
  10.    memcpy(_data, m._data, sizeof(double)*_cols*_rows );
  11. }
  12. return (*this) ;
  13. }
 

après bon, les tableaux 1D ....  :cry:

 
in_your_phion a écrit :


Que se passe t'il si on redéfini pas =, c'est juste une copie membre à membre ?


Oui et c'ets MAL

 
in_your_phion a écrit :


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 :

 
Code :
  1. Matrix m1(2,3) , m2(3,3), m3; //les matrices avec leurs tailles
  2. m1.display(); //affiche
  3. m2.display();
  4. m3 = m1*m2; // ligne 3
  5. //...
  6. //d'autres opérations à caractère très très intéressant ...
 

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.

Message cité 1 fois
Message édité par Joel F le 01-05-2008 à 10:45:52
n°1727170
skeye
Posté le 01-05-2008 à 10:46:36  profilanswer
 

ah tiens, j'avais mal compris la question, mais je comprends la réponse au moins .:D


Message édité par skeye le 01-05-2008 à 10:46:42

---------------
Can't buy what I want because it's free -
n°1727183
Ace17
Posté le 01-05-2008 à 11:21:11  profilanswer
 

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?

n°1727205
Joel F
Real men use unique_ptr
Posté le 01-05-2008 à 12:46:38  profilanswer
 

ca expliquerait un appel au destructeur, le 2e viendrait d'où.
Anyway, je veut tout le code svp

n°1727456
in_your_ph​ion
Posté le 02-05-2008 à 00:44:07  profilanswer
 

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 :
  1. Matrix operator*(const Matrix & m) {
  2.  Matrix res;
  3.  if ( _cols == m._rows ) {
  4.  res._data = new double [_rows * m._cols];
  5.  res._cols = m._cols;
  6.  res._rows = _rows;
  7.  for (int i = 0; i< res._rows; ++i )
  8.   for (int j = 0; j< res._cols; ++j ) {
  9.    res._data[j + i*res._cols] = 0;
  10.    for (int k=0;k < _cols ; ++k )
  11.     res._data[j + i*res._cols] += _data[k + i*_cols] * m._data[j + k*m._cols] ;
  12.   }
  13.  }
  14.  return res;
  15. }
 

j'ai bon ...?  :sweat:

 

(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 ?)


Message édité par in_your_phion le 02-05-2008 à 00:46:33
n°1727489
Joel F
Real men use unique_ptr
Posté le 02-05-2008 à 08:34:23  profilanswer
 

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 :o

 

sinon oui operartor() se surcharge sans probleme.

Message cité 1 fois
Message édité par Joel F le 02-05-2008 à 08:34:45
n°1727608
Taz
bisounours-codeur
Posté le 02-05-2008 à 13:14:19  profilanswer
 

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


Message édité par Taz le 02-05-2008 à 13:14:35
n°1727755
in_your_ph​ion
Posté le 02-05-2008 à 17:55:24  profilanswer
 

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 !
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 :o

 

sinon oui operartor() se surcharge sans probleme.

 

salut,

 

merci pour vos réponses encore 1 fois  :jap: 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  [:arg]

 

@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 ..  :cry:

 

ps : pour operator(), je voulais savoir si je peux l'utiliser dans operator*

 

merki!

 

ps : voici TOUT mon code (dans le .h) :

 


Code :
  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. const int N = 100;
  5. class my_exception : public exception {
  6. public:
  7. my_exception(const char * txt ) {
  8.  msg = new char [strlen(txt) +1];
  9.  strcpy_s(msg,strlen(txt)+1,txt);
  10. }
  11. virtual const char * what () const throw() {
  12.  return this->msg;
  13. }
  14. private:
  15. char * msg;
  16. };
  17. class Matrix {
  18. public:
  19. Matrix() : _cols(0), _rows(0), _data(0) { };
  20. ~Matrix () {
  21.  cout << "appel du destructeur" << endl;
  22. if (_data)
  23.  delete [] _data;
  24. } ;
  25. Matrix(int r, int c) {
  26.  //if ( r <= 0 && c  <= 0) throw BadIndex (" Matrix has wrong size." ) ;
  27.  _data = new double [r * c ];
  28.  for (int i=0; i< r*c; ++i)
  29.   _data[i] = (double) rand()/( RAND_MAX+1.0  )*N ;
  30.  _rows=r;
  31.  _cols=c;
  32. }
  33. //constructeur de copie
  34. Matrix (const Matrix & m) {
  35.  cout << "appel du constructeur de recopie" << endl;
  36.  if (m._data) {
  37.   _rows = m._rows;
  38.   _cols = m._cols;
  39.   _data = new double [_rows * _cols ];
  40.   memcpy(_data, m._data, sizeof(double)*_rows*_cols );
  41.  }
  42. }
  43. double operator()(int i, int j) const {
  44.  //throw exeption
  45.  return _data[j + i*_cols] ;
  46. }
  47. double& operator()(int i, int j) {
  48.  //throw exeption
  49.  return _data[j + i*_cols] ;
  50. }
  51. Matrix & operator=(const Matrix  & m) {
  52.  if (m != *this) {
  53.   _cols = m._cols;
  54.   _rows = m._rows;
  55.   if (_data)
  56.    delete [] _data;
  57.   _data = new double [_cols*_rows];
  58.   memcpy(_data, m._data, sizeof(double)*_cols*_rows );
  59.  }
  60.  return (*this) ;
  61. }
  62. Matrix operator+(const Matrix & m) {
  63.  Matrix res;
  64.  res._data = new double [m._rows * m._cols] ;
  65.  res._cols = _cols;
  66.  res._rows = _rows;
  67.  for (int i=0;i<_rows;++i)
  68.   for (int j=0;j<_cols;++j)
  69.    res._data[j + i*_cols] = _data[j + i*_cols] + m._data[j + i*_cols] ;
  70.  return res;
  71. }
  72. Matrix operator*(const Matrix & m) {
  73.  Matrix res;
  74.  if ( _cols == m._rows ) {
  75.  res._data = new double [_rows * m._cols];
  76.  res._cols = m._cols;
  77.  res._rows = _rows;
  78.  for (int i = 0; i< res._rows; ++i )
  79.   for (int j = 0; j< res._cols; ++j ) {
  80.    res._data[j + i*res._cols] = 0;
  81.    for (int k=0;k < _cols ; ++k )
  82.     res._data[j + i*res._cols] += _data[k + i*_cols] * m._data[j + k*m._cols] ;
  83.   }
  84.  }
  85.  return res;
  86. }
  87. void display() const {
  88.  if (_data != 0) {
  89.   cout.precision(4);
  90.   cout << "size=(" << _rows << ',' << _cols << ')' << endl;
  91.   for (int i=0;i<_rows;++i) {
  92.    for (int j=0;j<_cols;++j)
  93.     cout << fixed << _data[j + i*_cols] << '\t' ;
  94.    cout << endl;
  95.   }
  96.   cout << endl;
  97.  }
  98.  else
  99.   cout << "Matrix is empty." << endl;
  100. }
  101. //void showadd() { cout << _data << endl; }
  102. private:
  103. int _rows, _cols;
  104. double * _data;
  105. };
 

ps : la ligne 82 me génère l'erreur suivante :

 


error C2678: binary '!=' : no operator found which takes a left-hand operand of type 'const Matrix' (or there is no acceptable conversion)

 

ce serait pas plutot

 
Code :
  1. if ( &m != this)
 

?


Message édité par in_your_phion le 02-05-2008 à 18:10:57
mood
Publicité
Posté le 02-05-2008 à 17:55:24  profilanswer
 

n°1727789
Joel F
Real men use unique_ptr
Posté le 02-05-2008 à 19:43:21  profilanswer
 

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

n°1727874
in_your_ph​ion
Posté le 03-05-2008 à 02:11:21  profilanswer
 

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>.
 
Ca sert à rien d'attendre pour utiliser la STL à part se faire chier


 
ouaiiii ...bon ....
 
que penses tu de ma brand new version tunée avec la STL alors ????  :D  
 

Code :
  1. const int N = 100;
  2. class my_exception : public exception {
  3. public:
  4. my_exception(const char * txt ) {
  5.  msg.assign(txt);
  6.  }
  7. virtual const char * what () const throw() {
  8.  return this->msg.data();
  9. }
  10. private:
  11. string msg;
  12. };
  13. class Matrix {
  14. public:
  15. Matrix() : _cols(0), _rows(0) { };
  16. ~Matrix () { cout << "appel du destructeur" << endl; }
  17. Matrix(int r, int c) {
  18.  //if ( r <= 0 && c  <= 0) throw BadIndex (" Matrix has wrong size." ) ;
  19.  for (int i= 0; i< r*c; ++i)
  20.   _data.push_back ( (double) rand()/( RAND_MAX+1.0  )*N );
  21.  _rows=r;
  22.  _cols=c;
  23. }
  24. /* plus besoin d'un constructeur de copie ? */
  25. double operator()(int i, int j) const {
  26.  //throw exeption
  27.  return _data[j + i*_cols] ;
  28. }
  29. double& operator()(int i, int j) {
  30.  //throw exeption
  31.  return _data[j + i*_cols] ;
  32. }
  33. Matrix & operator=(const Matrix  & m) {
  34.  if ( &m != this ) {
  35.   _cols = m._cols;
  36.   _rows = m._rows;
  37.   _data = m._data;
  38.  }
  39.  return (*this) ;
  40. }
  41. Matrix operator+(const Matrix & m) {
  42.  try {
  43.  if ( m._rows != _rows ||  m._cols != _cols )
  44.   throw my_exception("Matrices have different size" );
  45.  } catch (my_exception & e) { cout << e.what() << endl; }
  46.  Matrix res;
  47.  res._data = _data ;
  48.  res._cols = _cols;
  49.  res._rows = _rows;
  50.  for (int i=0;i<_rows;++i)
  51.   for (int j=0;j<_cols;++j)
  52.    res._data[j + i*_cols] = _data[j + i*_cols] + m._data[j + i*_cols] ;
  53.  return res;
  54. }
  55. Matrix operator*(const Matrix & m) {
  56.  Matrix res(*this);
  57.  if ( _cols == m._rows ) {
  58.   for (int i = 0; i< res._rows; ++i )
  59.    for (int j = 0; j< res._cols; ++j ) {
  60.     res._data[j + i*res._cols] = 0;
  61.     for (int k=0;k < _cols ; ++k )
  62.      res._data[j + i*res._cols] += _data[k + i*_cols] * m._data[j + k*m._cols] ;
  63.    }
  64.  }
  65.  return res;
  66. }
  67. void display() const {
  68.  if ( _data.size() ) {
  69.   cout.precision(4);
  70.   cout << "size=(" << _rows << ',' << _cols << ')' << endl;
  71.   int k=0;
  72.   for (vector<double>::const_iterator i=_data.begin(); i != _data.end() ;++i) {
  73.    cout << fixed << *i << '\t' ;
  74.    ++k;
  75.    if (k == _cols) {
  76.     k=0;
  77.     cout << endl;
  78.    }
  79.   }
  80.   cout << endl;
  81.  }
  82.  else
  83.   cout << "Matrix is empty." << endl;
  84. }
  85. //void showadd() { cout << _data << endl; }
  86. private:
  87. int _rows, _cols;
  88. vector<double> _data;
  89. };


 
ça envoie ...?

n°1728131
Taz
bisounours-codeur
Posté le 04-05-2008 à 10:01:55  profilanswer
 

Si tu veux persister dans cette voie là, il manque des tas de const.

n°1728133
Joel F
Real men use unique_ptr
Posté le 04-05-2008 à 10:23:11  profilanswer
 

et je maintiens que * est canoniquement une fonction libre qui utilise la fonction membre += :o

n°1728280
Taz
bisounours-codeur
Posté le 04-05-2008 à 20:10:11  profilanswer
 

Joel F a écrit :

et je maintiens que * est canoniquement une fonction libre qui utilise la fonction membre += :o


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 ?

n°1728290
Joel F
Real men use unique_ptr
Posté le 04-05-2008 à 20:38:42  profilanswer
 

pour le papier j'en cherche encore. Si j'en trouve pas j'en ecrirais un :o
sinon, en quoi *= n'a pas de sens ?

n°1728298
Taz
bisounours-codeur
Posté le 04-05-2008 à 20:55:29  profilanswer
 

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

n°1728306
Joel F
Real men use unique_ptr
Posté le 04-05-2008 à 21:56:37  profilanswer
 

Certes, je sais plus comment j'ai contourner le probleme dans NT2

n°1728312
Taz
bisounours-codeur
Posté le 04-05-2008 à 22:03:18  profilanswer
 

Ouais enfin bon, tu vois le dilemne operator?= / operator? / friend / etc

n°1728313
Taz
bisounours-codeur
Posté le 04-05-2008 à 22:08:29  profilanswer
 

bref tu vois quoi comme forme canonique quand operator?= ne s'implémente en fait qu'en utilisant operator? ?

n°1728339
Joel F
Real men use unique_ptr
Posté le 04-05-2008 à 23:07:24  profilanswer
 

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 ?

n°1728397
Taz
bisounours-codeur
Posté le 05-05-2008 à 09:51:29  profilanswer
 

oui

n°1728412
Joel F
Real men use unique_ptr
Posté le 05-05-2008 à 10:13:59  profilanswer
 

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

n°1728650
Taz
bisounours-codeur
Posté le 05-05-2008 à 14:59:37  profilanswer
 

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 ?

n°1728830
in_your_ph​ion
Posté le 05-05-2008 à 22:28:15  profilanswer
 

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  :sweat:

n°1728851
Taz
bisounours-codeur
Posté le 06-05-2008 à 00:06:54  profilanswer
 

ton operator+ par exemple

n°1729780
in_your_ph​ion
Posté le 07-05-2008 à 23:28:14  profilanswer
 

Taz a écrit :

ton operator+ par exemple


 
salut,
je vois pas  :cry: ... il manque un const dans operator+ ? ou ca ??

n°1729822
Joel F
Real men use unique_ptr
Posté le 08-05-2008 à 08:27:33  profilanswer
 

Matrix operator+(const Matrix & m) const
 
tout simplement.
Une méthode qui ne modifie pas l'état d'un objet est par def. const.

n°1730036
jesus_chri​st
votre nouveau dieu
Posté le 08-05-2008 à 20:21:20  profilanswer
 

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.

n°1730037
Joel F
Real men use unique_ptr
Posté le 08-05-2008 à 20:28:30  profilanswer
 

c'est pas prévu par le standard. gcc le fait mais pas VC++ (ou l'inverse)

n°1730044
jesus_chri​st
votre nouveau dieu
Posté le 08-05-2008 à 20:50:57  profilanswer
 

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.

n°1730045
jesus_chri​st
votre nouveau dieu
Posté le 08-05-2008 à 20:54:04  profilanswer
 

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).

n°1730046
jesus_chri​st
votre nouveau dieu
Posté le 08-05-2008 à 20:55:37  profilanswer
 

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

n°1730049
Joel F
Real men use unique_ptr
Posté le 08-05-2008 à 21:02:51  profilanswer
 

ah ok ^^ c'est le delete d'un unallocated pointer qui chouine, OK ;) c'est noté :o

n°1730055
jesus_chri​st
votre nouveau dieu
Posté le 08-05-2008 à 21:11:19  profilanswer
 

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...).

n°1730428
in_your_ph​ion
Posté le 10-05-2008 à 02:52:28  profilanswer
 

Joel F a écrit :

Matrix operator+(const Matrix & m) const

 

tout simplement.
Une méthode qui ne modifie pas l'état d'un objet est par def. const.

 

ok merci pour vos réponses. Puisqu'on parle de la STL, j'ai une petite autre question siouplé...  :whistle:

 

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 :
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <vector>
  4. using namespace std;
  5. class tablo2dint {
  6.   public:
  7. tablo2dint (size_t x=0, size_t y=0) : _sx(x), _sy(y) {
  8.   data.resize ( _sy ) ;
  9.   for (int i=0;i<_sy;++i)
  10.      data[i].resize( _sx ) ;
  11.    for (int i=0;i<_sy;++i)
  12.       for (int j=0;j<_sx;++j )
  13.           data[i][j] = 2;
  14.     }
  15. void display() {
  16.    cout << "display" << endl;
  17.    for (int i=0;i<_sy;++i) {
  18.       for (int j=0;j<_sx;++j )
  19.            cout <<  setw(3) << data[i][j] ;
  20.       cout << endl;   
  21.       }
  22.     }
  23.   private:
  24.     int _sx;
  25.     int _sy;
  26.     vector<vector<int> >  data;
  27. };
  28. int main() {
  29.   tablo2dint A(3,2);
  30.   A.display();
  31.   return 0;
  32. }
 


display
  2  2  2
  2  2  2  


je voudrais savoir si ca a du sens de faire :

 
Code :
  1. vector<vector<int> >  * data; // au lieu de  vector<vector<int> >  data;
 

?

 

si oui comment je peux initialiser ce pointeur ...

 

merci d'avance  :hello:


Message édité par in_your_phion le 10-05-2008 à 02:59:49
n°1730433
Joel F
Real men use unique_ptr
Posté le 10-05-2008 à 08:56:25  profilanswer
 

vector<vector<int> > suffit, mais c'est inefficace, mattes du coté de boost::multi_array

n°1730441
jesus_chri​st
votre nouveau dieu
Posté le 10-05-2008 à 10:05:23  profilanswer
 

Code :
  1. tablo2dint(size_t x=0, size_t y=0)
  2. :   _sx(x)
  3. ,   _sy(y)
  4. ,   data( x, std::vector< int >( y, 2 ) )
  5. {
  6. }


 
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.

Message cité 1 fois
Message édité par jesus_christ le 10-05-2008 à 10:07:28
n°1730518
in_your_ph​ion
Posté le 10-05-2008 à 17:08:12  profilanswer
 

jesus_christ a écrit :

Code :
  1. tablo2dint(size_t x=0, size_t y=0)
  2. :   _sx(x)
  3. ,   _sy(y)
  4. ,   data( x, std::vector< int >( y, 2 ) )
  5. {
  6. }


 
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.


 
 :sweat:  :o  
 
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
 
...
 
 

n°1730544
jesus_chri​st
votre nouveau dieu
Posté le 10-05-2008 à 20:18:32  profilanswer
 

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

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  appel du destructeur et opérateurs

 

Sujets relatifs
Appel aux pros de GTK et manipulation des images. J'avance pas !problème débutant: appel méthode
Appel dll VB depuis VC++[RESOLU] "applet not initiated" : quelle erreur dans le code HTML ?
appel d'un exécutable[C++] Destructeur ? Comprends pas..
[resolu] CSS - Appel d'un div codé ailleurssurcharge d'opérateurs
est-il possible de faire un appel dynamique à une procédure??appel d'un executable
Plus de sujets relatifs à : appel du destructeur et opérateurs


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)