appel du destructeur et opérateurs

appel du destructeur et opérateurs - C++ - Programmation

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

 
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
Reply

Marsh Posté le 30-04-2008 à 23:16:19   

Reply

Marsh Posté le 01-05-2008 à 10:45:27    

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


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 01-05-2008 à 10:45:34    

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
Reply

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 .:D


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

---------------
Can't buy what I want because it's free -
Reply

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?

Reply

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

Reply

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

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

 

sinon oui operartor() se surcharge sans probleme.

Message cité 1 fois
Message édité par Joel F le 02-05-2008 à 08:34:45
Reply

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


Message édité par Taz le 02-05-2008 à 13:14:35
Reply

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 !
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
Reply

Marsh Posté le 02-05-2008 à 17:55:24   

Reply

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

Reply

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

Reply

Marsh Posté le 04-05-2008 à 10:01:55    

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

Reply

Marsh Posté le 04-05-2008 à 10:23:11    

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

Reply

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

Reply

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 :o
sinon, en quoi *= n'a pas de sens ?

Reply

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

Reply

Marsh Posté le 04-05-2008 à 21:56:37    

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

Reply

Marsh Posté le 04-05-2008 à 22:03:18    

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

Reply

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

Reply

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 ?

Reply

Marsh Posté le 05-05-2008 à 09:51:29    

oui

Reply

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

Reply

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 ?

Reply

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

Reply

Marsh Posté le 06-05-2008 à 00:06:54    

ton operator+ par exemple

Reply

Marsh Posté le 07-05-2008 à 23:28:14    

Taz a écrit :

ton operator+ par exemple


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

Reply

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.

Reply

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.

Reply

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)

Reply

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.

Reply

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

Reply

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

Reply

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

Reply

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

Reply

Marsh Posté le 10-05-2008 à 02:52:28    

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
Reply

Marsh Posté le 10-05-2008 à 08:56:25    

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

Reply

Marsh Posté le 10-05-2008 à 10:05:23    

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
Reply

Marsh Posté le 10-05-2008 à 17:08:12    

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

Reply

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

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed