Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
(mettons, des rectangles pour paver un plus grand carré)
En fait, ma matrice doit être de taille variable ...
L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
(mettons, des rectangles pour paver un plus grand carré)
En fait, ma matrice doit être de taille variable ...
L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
(mettons, des rectangles pour paver un plus grand carré)
En fait, ma matrice doit être de taille variable ...
L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
En fait, ma matrice doit être de taille variable ...
Je ne suis pas arrivé à trouver la bonne déclaration dans .h, ni le bon code
dans .cpp
L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
En fait, ma matrice doit être de taille variable ...
Je ne suis pas arrivé à trouver la bonne déclaration dans .h, ni le bon code
dans .cpp
L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
En fait, ma matrice doit être de taille variable ...
Je ne suis pas arrivé à trouver la bonne déclaration dans .h, ni le bon code
dans .cpp
L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
eb wrote on 11/06/2006 08:20:Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
(disons T, la "classe quelconque")
une matrice de pointeurs d'instances ou une matrice d'instances ?En fait, ma matrice doit être de taille variable ...
cela exclut un "T[R][K]" statique mais ne définit pas complètement le
comportement voulu:
- qui est responsable de l'allocation / destruction des éléments ?
si c'est la matrice, celle-ci peut stocker des références (un T[][]),
sinon elle définira surement un T*[][] afin de simplifier la gestion des
élements (pas indispensable si T est "léger", avec un opérateur de copie
implicite ou léger).
- la matrice doit-elle être redimensionable ?
si c'est le cas, il est également plus simple que chaque cellule soit un
T*, ceci permettra de copier les pointeurs dans une nouvelle matrice
redimensionnée, plutôt que de cloner les références stockées.
- est-ce que toutes les lignes ont la même taille ?
si c'est le cas, une approche T**[] est adaptée et minimisera les
overheads; si ce n'est pas le cas (la matrice est un vecteur de liste),
la solution de Fabien est plus adaptée.Je ne suis pas arrivé à trouver la bonne déclaration dans .h, ni le bon
code dans .cpp
supposons les lignes homogènes et les objets légers, une définition
possible est:
template <class T>
class Matrice {
private:
typedef T* Tptr;
T** items;
int rows, cols;
public:
Matrice(int row, int col){
cols = col;
items = new Tptr[rows = row];
for (register int i = 0; i < row; ++i)
items[i] = new T[col];
}
virtual ~Matrice(){
for (register int i = 0; i < rows; ++i){
if (items[i])
delete [] items[i];
}
delete [] items;
}
...
};
si la matrice contient des T*, on écrira:
template <class T>
class Matrice {
private:
typedef T* Tptr;
Tptr** items;
int rows, cols;
public:
Matrice(int row, int col){
cols = col;
items = new Tptr*[rows = row];
for (register int i = 0; i < row; ++i){
items[i] = new Tptr[col];
for (register int k = 0; k < col; ++k)
items[i][k] = null;
}
}
virtual ~Matrice(){
for (register int i = 0; i < rows; ++i){
if (items[i]){
for (register int k = 0; k < cols; ++k)
if (items[i][k])
delete items[i][k];
delete [] items[i];
}
}
delete [] items;
}
...
};L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
l'opérateur [] peut ne pas être la meilleure solution.
avec une solution vecteur de list, c'est correct car MonPavé[i] retourne
un std::vector qui réalisera tous les contrôles requis pour la
résolution de [j]
si par contre, le pavé est un simple array (un T**{*}), [i] retournera
un T* (ou un T**) sur lequel plus aucun controle (de validité d'indice)
ne peut être appliqué, dans un tel cas, on pourra préférer la notation
T{*|&} t = MonPavé(row, line);
cas T[][]
T& operator() (int r, int k) const {
if (r >= rows) throw "error";
if (k >= cols) throw "error";
return items[r][k];
}
ou, cas T*[][]
T* operator() (int r, int k) const {
if (r >= rows) throw "error";
if (k >= cols) throw "error";
return items[r][k];
}
eb wrote on 11/06/2006 08:20:
Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
(disons T, la "classe quelconque")
une matrice de pointeurs d'instances ou une matrice d'instances ?
En fait, ma matrice doit être de taille variable ...
cela exclut un "T[R][K]" statique mais ne définit pas complètement le
comportement voulu:
- qui est responsable de l'allocation / destruction des éléments ?
si c'est la matrice, celle-ci peut stocker des références (un T[][]),
sinon elle définira surement un T*[][] afin de simplifier la gestion des
élements (pas indispensable si T est "léger", avec un opérateur de copie
implicite ou léger).
- la matrice doit-elle être redimensionable ?
si c'est le cas, il est également plus simple que chaque cellule soit un
T*, ceci permettra de copier les pointeurs dans une nouvelle matrice
redimensionnée, plutôt que de cloner les références stockées.
- est-ce que toutes les lignes ont la même taille ?
si c'est le cas, une approche T**[] est adaptée et minimisera les
overheads; si ce n'est pas le cas (la matrice est un vecteur de liste),
la solution de Fabien est plus adaptée.
Je ne suis pas arrivé à trouver la bonne déclaration dans .h, ni le bon
code dans .cpp
supposons les lignes homogènes et les objets légers, une définition
possible est:
template <class T>
class Matrice {
private:
typedef T* Tptr;
T** items;
int rows, cols;
public:
Matrice(int row, int col){
cols = col;
items = new Tptr[rows = row];
for (register int i = 0; i < row; ++i)
items[i] = new T[col];
}
virtual ~Matrice(){
for (register int i = 0; i < rows; ++i){
if (items[i])
delete [] items[i];
}
delete [] items;
}
...
};
si la matrice contient des T*, on écrira:
template <class T>
class Matrice {
private:
typedef T* Tptr;
Tptr** items;
int rows, cols;
public:
Matrice(int row, int col){
cols = col;
items = new Tptr*[rows = row];
for (register int i = 0; i < row; ++i){
items[i] = new Tptr[col];
for (register int k = 0; k < col; ++k)
items[i][k] = null;
}
}
virtual ~Matrice(){
for (register int i = 0; i < rows; ++i){
if (items[i]){
for (register int k = 0; k < cols; ++k)
if (items[i][k])
delete items[i][k];
delete [] items[i];
}
}
delete [] items;
}
...
};
L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
l'opérateur [] peut ne pas être la meilleure solution.
avec une solution vecteur de list, c'est correct car MonPavé[i] retourne
un std::vector qui réalisera tous les contrôles requis pour la
résolution de [j]
si par contre, le pavé est un simple array (un T**{*}), [i] retournera
un T* (ou un T**) sur lequel plus aucun controle (de validité d'indice)
ne peut être appliqué, dans un tel cas, on pourra préférer la notation
T{*|&} t = MonPavé(row, line);
cas T[][]
T& operator() (int r, int k) const {
if (r >= rows) throw "error";
if (k >= cols) throw "error";
return items[r][k];
}
ou, cas T*[][]
T* operator() (int r, int k) const {
if (r >= rows) throw "error";
if (k >= cols) throw "error";
return items[r][k];
}
eb wrote on 11/06/2006 08:20:Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
(disons T, la "classe quelconque")
une matrice de pointeurs d'instances ou une matrice d'instances ?En fait, ma matrice doit être de taille variable ...
cela exclut un "T[R][K]" statique mais ne définit pas complètement le
comportement voulu:
- qui est responsable de l'allocation / destruction des éléments ?
si c'est la matrice, celle-ci peut stocker des références (un T[][]),
sinon elle définira surement un T*[][] afin de simplifier la gestion des
élements (pas indispensable si T est "léger", avec un opérateur de copie
implicite ou léger).
- la matrice doit-elle être redimensionable ?
si c'est le cas, il est également plus simple que chaque cellule soit un
T*, ceci permettra de copier les pointeurs dans une nouvelle matrice
redimensionnée, plutôt que de cloner les références stockées.
- est-ce que toutes les lignes ont la même taille ?
si c'est le cas, une approche T**[] est adaptée et minimisera les
overheads; si ce n'est pas le cas (la matrice est un vecteur de liste),
la solution de Fabien est plus adaptée.Je ne suis pas arrivé à trouver la bonne déclaration dans .h, ni le bon
code dans .cpp
supposons les lignes homogènes et les objets légers, une définition
possible est:
template <class T>
class Matrice {
private:
typedef T* Tptr;
T** items;
int rows, cols;
public:
Matrice(int row, int col){
cols = col;
items = new Tptr[rows = row];
for (register int i = 0; i < row; ++i)
items[i] = new T[col];
}
virtual ~Matrice(){
for (register int i = 0; i < rows; ++i){
if (items[i])
delete [] items[i];
}
delete [] items;
}
...
};
si la matrice contient des T*, on écrira:
template <class T>
class Matrice {
private:
typedef T* Tptr;
Tptr** items;
int rows, cols;
public:
Matrice(int row, int col){
cols = col;
items = new Tptr*[rows = row];
for (register int i = 0; i < row; ++i){
items[i] = new Tptr[col];
for (register int k = 0; k < col; ++k)
items[i][k] = null;
}
}
virtual ~Matrice(){
for (register int i = 0; i < rows; ++i){
if (items[i]){
for (register int k = 0; k < cols; ++k)
if (items[i][k])
delete items[i][k];
delete [] items[i];
}
}
delete [] items;
}
...
};L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
l'opérateur [] peut ne pas être la meilleure solution.
avec une solution vecteur de list, c'est correct car MonPavé[i] retourne
un std::vector qui réalisera tous les contrôles requis pour la
résolution de [j]
si par contre, le pavé est un simple array (un T**{*}), [i] retournera
un T* (ou un T**) sur lequel plus aucun controle (de validité d'indice)
ne peut être appliqué, dans un tel cas, on pourra préférer la notation
T{*|&} t = MonPavé(row, line);
cas T[][]
T& operator() (int r, int k) const {
if (r >= rows) throw "error";
if (k >= cols) throw "error";
return items[r][k];
}
ou, cas T*[][]
T* operator() (int r, int k) const {
if (r >= rows) throw "error";
if (k >= cols) throw "error";
return items[r][k];
}
On Sun, 11 Jun 2006 08:20:20 +0200, eb :Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
(mettons, des rectangles pour paver un plus grand carré)
En fait, ma matrice doit être de taille variable ...
Ça se fait assez facilement en se basant sur un tableau de tableaux
(std::vector<std::vector<T> >, par exemple).
template <class T>
class Matrice
{
public:
typedef std::vector<T> Ligne;
typedef std::vector<Ligne> Data;
private:
Data data;
};
Il ne reste plus qu'à rajouter les fonctions qui vont bien.L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
Note que tu peux faire un truc très basique avec
typedef std::vector<std::vector<Rectangle> > MatriceDeRectangles;
MatriceDeRectangles mon_pave (largeur, hauteur);
-> "mon_pave[i][j]" est alors correct, si i et j ont de bonnes
valeurs.
Note néanmoins que tu risques de vite trouver ça insuffisant.
Mieux vaut créer une classe "Matrice" propre.
On Sun, 11 Jun 2006 08:20:20 +0200, eb <eb@nowhere.com>:
Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
(mettons, des rectangles pour paver un plus grand carré)
En fait, ma matrice doit être de taille variable ...
Ça se fait assez facilement en se basant sur un tableau de tableaux
(std::vector<std::vector<T> >, par exemple).
template <class T>
class Matrice
{
public:
typedef std::vector<T> Ligne;
typedef std::vector<Ligne> Data;
private:
Data data;
};
Il ne reste plus qu'à rajouter les fonctions qui vont bien.
L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
Note que tu peux faire un truc très basique avec
typedef std::vector<std::vector<Rectangle> > MatriceDeRectangles;
MatriceDeRectangles mon_pave (largeur, hauteur);
-> "mon_pave[i][j]" est alors correct, si i et j ont de bonnes
valeurs.
Note néanmoins que tu risques de vite trouver ça insuffisant.
Mieux vaut créer une classe "Matrice" propre.
On Sun, 11 Jun 2006 08:20:20 +0200, eb :Je cherche à créer une matrice à 2 dimensions d'une classe quelconque.
(mettons, des rectangles pour paver un plus grand carré)
En fait, ma matrice doit être de taille variable ...
Ça se fait assez facilement en se basant sur un tableau de tableaux
(std::vector<std::vector<T> >, par exemple).
template <class T>
class Matrice
{
public:
typedef std::vector<T> Ligne;
typedef std::vector<Ligne> Data;
private:
Data data;
};
Il ne reste plus qu'à rajouter les fonctions qui vont bien.L'idée est de pouvoir dans le code, initialiser un pavage de la bonne
taille, puis d'accéder à mes éléments avec MonPavé[i][j]
Note que tu peux faire un truc très basique avec
typedef std::vector<std::vector<Rectangle> > MatriceDeRectangles;
MatriceDeRectangles mon_pave (largeur, hauteur);
-> "mon_pave[i][j]" est alors correct, si i et j ont de bonnes
valeurs.
Note néanmoins que tu risques de vite trouver ça insuffisant.
Mieux vaut créer une classe "Matrice" propre.
unsigned rows = 25
std::vector< QCanvasLine > v(rows) ;
error: no matching function for call to `QCanvasLine::QCanvasLine()'
/usr/qt/3/include/qcanvas.h:685: note: candidates are:
QCanvasLine::QCanvasLine(const QCanvasLine&)
/usr/qt/3/include/qcanvas.h:687: note: QCanvasLine::QCanvasLine(QCanvas*)
unsigned rows = 25
std::vector< QCanvasLine > v(rows) ;
error: no matching function for call to `QCanvasLine::QCanvasLine()'
/usr/qt/3/include/qcanvas.h:685: note: candidates are:
QCanvasLine::QCanvasLine(const QCanvasLine&)
/usr/qt/3/include/qcanvas.h:687: note: QCanvasLine::QCanvasLine(QCanvas*)
unsigned rows = 25
std::vector< QCanvasLine > v(rows) ;
error: no matching function for call to `QCanvasLine::QCanvasLine()'
/usr/qt/3/include/qcanvas.h:685: note: candidates are:
QCanvasLine::QCanvasLine(const QCanvasLine&)
/usr/qt/3/include/qcanvas.h:687: note: QCanvasLine::QCanvasLine(QCanvas*)
On Sun, 11 Jun 2006 20:35:49 +0200, eb :unsigned rows = 25
Je n'aime pas beaucoup ce nom de variable : "rows" veut dire "lignes",
pas "nombre de lignes".
Généralement j'écris "nb_rows" (ou "nb_lignes").
Par ailleurs, il y a de fortes chances pour que ta variable soit une
constante :
static unsigned const nb_rows= 25;
On Sun, 11 Jun 2006 20:35:49 +0200, eb <eb@nowhere.com>:
unsigned rows = 25
Je n'aime pas beaucoup ce nom de variable : "rows" veut dire "lignes",
pas "nombre de lignes".
Généralement j'écris "nb_rows" (ou "nb_lignes").
Par ailleurs, il y a de fortes chances pour que ta variable soit une
constante :
static unsigned const nb_rows= 25;
On Sun, 11 Jun 2006 20:35:49 +0200, eb :unsigned rows = 25
Je n'aime pas beaucoup ce nom de variable : "rows" veut dire "lignes",
pas "nombre de lignes".
Généralement j'écris "nb_rows" (ou "nb_lignes").
Par ailleurs, il y a de fortes chances pour que ta variable soit une
constante :
static unsigned const nb_rows= 25;
Ta classe "QCanvasLine" n'a pas de constructeur par défaut. Or, il en
faut un pour obtenir un vector<QCanvasLine>.
/usr/qt/3/include/qcanvas.h:685: note: candidates are:
QCanvasLine::QCanvasLine(const QCanvasLine&)
/usr/qt/3/include/qcanvas.h:687: note: QCanvasLine::QCanvasLine(QCanvas*)
La liste des autres constructeurs (qui ne t'es guère utile).
Ta classe "QCanvasLine" n'a pas de constructeur par défaut. Or, il en
faut un pour obtenir un vector<QCanvasLine>.
/usr/qt/3/include/qcanvas.h:685: note: candidates are:
QCanvasLine::QCanvasLine(const QCanvasLine&)
/usr/qt/3/include/qcanvas.h:687: note: QCanvasLine::QCanvasLine(QCanvas*)
La liste des autres constructeurs (qui ne t'es guère utile).
Ta classe "QCanvasLine" n'a pas de constructeur par défaut. Or, il en
faut un pour obtenir un vector<QCanvasLine>.
/usr/qt/3/include/qcanvas.h:685: note: candidates are:
QCanvasLine::QCanvasLine(const QCanvasLine&)
/usr/qt/3/include/qcanvas.h:687: note: QCanvasLine::QCanvasLine(QCanvas*)
La liste des autres constructeurs (qui ne t'es guère utile).
voire même unsigned /int/, ce typage implicite est un héritage désuet
du C K&R.
voire même unsigned /int/, ce typage implicite est un héritage désuet
du C K&R.
voire même unsigned /int/, ce typage implicite est un héritage désuet
du C K&R.
On Sun, 11 Jun 2006 20:35:49 +0200, eb :unsigned rows = 25
Je n'aime pas beaucoup ce nom de variable : "rows" veut dire "lignes",
pas "nombre de lignes".
Généralement j'écris "nb_rows" (ou "nb_lignes").
On Sun, 11 Jun 2006 20:35:49 +0200, eb <eb@nowhere.com>:
unsigned rows = 25
Je n'aime pas beaucoup ce nom de variable : "rows" veut dire "lignes",
pas "nombre de lignes".
Généralement j'écris "nb_rows" (ou "nb_lignes").
On Sun, 11 Jun 2006 20:35:49 +0200, eb :unsigned rows = 25
Je n'aime pas beaucoup ce nom de variable : "rows" veut dire "lignes",
pas "nombre de lignes".
Généralement j'écris "nb_rows" (ou "nb_lignes").
Sylvain writes:voire même unsigned /int/, ce typage implicite est un héritage désuet
du C K&R.
Pourquoi désuet ?
plus que pourquoi, dans quel cas ?
Sylvain <noSpam@mail.net> writes:
voire même unsigned /int/, ce typage implicite est un héritage désuet
du C K&R.
Pourquoi désuet ?
plus que pourquoi, dans quel cas ?
Sylvain writes:voire même unsigned /int/, ce typage implicite est un héritage désuet
du C K&R.
Pourquoi désuet ?
plus que pourquoi, dans quel cas ?