Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Création d'une classe de matrice -> opérateur [][]

19 réponses
Avatar
TigrouMeow
Hello ;)

Je pose décidément beaucoup de questions en ce moment... j'en ai aujourd'hui
une plus interressante je suppose :)

Voilà, j'aimerais programmer une classe de gestion de matrice. A priori ça
n'existe pas dans la std ni la stl. Le problème qui se pose à moi c'est que
j'aimerais utiliser l'opérateur [][] sur ma classe.

Exemple :
a = matrix[x][y];

Si possible, j'aimerais qu'on puisse faire aussi un matrix[x][y] = a, je
sais qu'en C# on utilise les opérateurs get et set pour faire cela, mais en
C++ je vois pas. Voilà deux questions en une ! Je vous remercie une fois de
plus pour l'aide que vous pourrez m'apporter... :)

--
TigrouMeow :)
================================
Le site des fournisseurs d'accès :
http://www.fai-fr.com
================================

10 réponses

1 2
Avatar
Luc Hermitte
"TigrouMeow" wrote in
news:416c60f8$0$3743$:

Je pose décidément beaucoup de questions en ce moment... j'en ai
aujourd'hui une plus interressante je suppose :)


Disons une grande classique, et loin d'être inintéressante vu tout ce qui
est soulevé derrière.

Voilà, j'aimerais programmer une classe de gestion de matrice. A
priori ça n'existe pas dans la std ni la stl.


Blitz++, boost::uBLAS, MTL, newmat, ... et j'en j'oublie très
certainement.

Le problème qui se pose
à moi c'est que j'aimerais utiliser l'opérateur [][] sur ma classe.


Il n'y a pas d'opérateur [][]. Il te faut renvoyer une classe proxy avec
l'opérateur[]. Ici le nom du proxy est facile à trouver : "vecteur"


--
Luc Hermitte <hermitte at free.fr>
FAQ de <news:fr.comp.lang.c++> :
<http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/>
Dejanews : <http://groups.google.com/advanced_group_search>

Avatar
Fabien LE LEZ
On Wed, 13 Oct 2004 00:55:51 +0200, "TigrouMeow"
:

a = matrix[x][y];
Si possible, j'aimerais qu'on puisse faire aussi un matrix[x][y] = a


Tout passe bien sûr par la définition de Matrice::operator[], puisque
tu cherches à définir un opérateur [] sur ta classe.

De deux choses l'une :

1/ Ta classe est basée sur un tableau à deux dimensions. Pas de
problème, ça marche tout seul :

class Matrice
{
public:
typedef std::vector <int> Ligne;
typedef std::vector <Ligne> Contenu;

Ligne & operator[] (int n);
{ return contenu[n]; }

private:
Contenu contenu;
};

[Note : je te laisse rajouter la version constante de l'opérateur]

2/ Ta classe est basée sur autre chose (par exemple, un tableau à une
dimension). Dans ce cas, il faut utiliser ce qu'on appelle un proxy :
l'opérateur [] de ta classe renvoie un proxy, et l'opérateur [] du
proxy renvoie l'élément auquel tu cherches à accéder.

class Matrice
{
public:
typedef std::vector <int> Contenu;

class Proxy
{
public:
Proxy (Matrice::Contenu::iterator debut_ligne_) :
debut_ligne (debut_ligne_) {}
int & operator[] (int n) { return *(debut_ligne+n); }
private:
Matrice::Contenu::iterator debut_ligne;
};

Proxy & operator[] (int n)
{ return Proxy (contenu.begin() + n*taille_ligne); }

private:
Contenu contenu;
};

[Note : là encore, je te laisse rajouter la version const]


--
;-)

Avatar
Fabien LE LEZ
On Wed, 13 Oct 2004 01:19:35 +0200, Luc Hermitte
:

Ici le nom du proxy est facile à trouver : "vecteur"


VecteurLigne ou VecteurColonne ?


--
;-)

Avatar
Loïc Joly
TigrouMeow wrote:

Hello ;)

Je pose décidément beaucoup de questions en ce moment... j'en ai aujourd'hui
une plus interressante je suppose :)

Voilà, j'aimerais programmer une classe de gestion de matrice. A priori ça
n'existe pas dans la std ni la stl. Le problème qui se pose à moi c'est que
j'aimerais utiliser l'opérateur [][] sur ma classe.


Une autre slution par rapport à celles proposées est d'oublier
l'écriture en [][], pour la remplacer par une écriture en ( , ), ce qui
évite de devoir écrire une classe proxy.

--
Loïc

Avatar
Andre Heinen
On Wed, 13 Oct 2004 00:55:51 +0200, "TigrouMeow"
wrote:

Voilà, j'aimerais programmer une classe de gestion de matrice.


Voir la FAQ, question 13.8:
http://www.ensta.fr/~diam/c++/online/c++-faq-lite__FR/operator-overloading-fr.html#[13.8]

A priori ça
n'existe pas dans la std ni la stl. Le problème qui se pose à moi c'est que
j'aimerais utiliser l'opérateur [][] sur ma classe.


Ce n'est peut-être pas une bonne idée. Cline conseille
d'utiliser operator(). Voir la FAQ suivante:
http://www.ensta.fr/~diam/c++/online/c++-faq-lite__FR/operator-overloading-fr.html#[13.9]
Je te laisse lire les explications et faire ton choix.

Si possible, j'aimerais qu'on puisse faire aussi un matrix[x][y] = a,


Aucun problème. Tu as dû constater que l'exemple de Fabien
retourne non pas un int, mais une référence. C'est ça le
secret... :-)

--
Andre Heinen
My address, rot13-encoded: n qbg urvara ng rhebcrnayvax qbg pbz

Avatar
Andre Heinen
On Wed, 13 Oct 2004 01:39:34 +0200, Fabien LE LEZ
wrote:

class Matrice
{
public:
typedef std::vector <int> Contenu;

class Proxy
{
public:
Proxy (Matrice::Contenu::iterator debut_ligne_) :
debut_ligne (debut_ligne_) {}
int & operator[] (int n) { return *(debut_ligne+n); }
private:
Matrice::Contenu::iterator debut_ligne;
};

Proxy & operator[] (int n)
{ return Proxy (contenu.begin() + n*taille_ligne); }


Attention, tu retournes une référence sur un temporaire.
Proxy::operator[] doit retourner une référence, mais pas
Matrice::operator[].

private:
Contenu contenu;
};


--
Andre Heinen
My address, rot13-encoded: n qbg urvara ng rhebcrnayvax qbg pbz

Avatar
kanze
Fabien LE LEZ wrote in message
news:...
On Wed, 13 Oct 2004 00:55:51 +0200, "TigrouMeow"
:

a = matrix[x][y];
Si possible, j'aimerais qu'on puisse faire aussi un matrix[x][y] = a


Tout passe bien sûr par la définition de Matrice::operator[], puisque
tu cherches à définir un opérateur [] sur ta classe.

De deux choses l'une :

1/ Ta classe est basée sur un tableau à deux dimensions. Pas de
problème, ça marche tout seul :

class Matrice
{
public:
typedef std::vector <int> Ligne;
typedef std::vector <Ligne> Contenu;

Ligne & operator[] (int n);
{ return contenu[n]; }

private:
Contenu contenu;
};

[Note : je te laisse rajouter la version constante de l'opérateur]

2/ Ta classe est basée sur autre chose (par exemple, un tableau à une
dimension). Dans ce cas, il faut utiliser ce qu'on appelle un proxy :
l'opérateur [] de ta classe renvoie un proxy, et l'opérateur [] du
proxy renvoie l'élément auquel tu cherches à accéder.

class Matrice
{
public:
typedef std::vector <int> Contenu;

class Proxy
{
public:
Proxy (Matrice::Contenu::iterator debut_ligne_) :
debut_ligne (debut_ligne_) {}
int & operator[] (int n) { return *(debut_ligne+n); }
private:
Matrice::Contenu::iterator debut_ligne;
};

Proxy & operator[] (int n)
^^^


Tu sais mieux que ça, j'espère:-). On ne renvoie pas une référence à un
temporaire.

{ return Proxy (contenu.begin() + n*taille_ligne); }

private:
Contenu contenu;
};


Dans ce cas-ci, on peut quand même simplifier le Proxy beaucoup. Quelque
chose comme :

typedef int* Proxy ;

ferait l'affaire, par exemple, avec:

Proxy Matrice::operator[]( int n )
{
return &contenu[ n * taille_ligne ] ;
}

Mais c'est un cas particulier ; il vaut la peine de connaître la
technique du Proxy en tout cas.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Boris Sargos
Salut,

après toutes les réponses que tu as eues, je n'ai pas grand chose à ajouter.
Cela dit, je te conseille de jeter un oeil sur le bouquin de Stroustrup. Il
donne de bonnes bases pour construire une classe Matrice. Sa méthode repose
sur l'utilisation d'un proxy qui est en l'ocurrence de type valarray. Tu
pourras trouver sur internet le code source de la classe Slice_iter.
Le code que Stroustrup fournit n'est pas simple, mais riche en
enseignements, et te donnera de bonnes pistes pour ce que tu veux faire.
Avatar
Boris Sargos
Pourquoi pas une bonne idée ?
Ca dépend comment c'est implémenté derrière !
Effectivement le cas du tableau de tableaux n'est pas efficace. Mais dans le
cas de slice et slice_array, ça l'est beaucoup plus. C'est la méthode que
j'ai adoptée pour mes calculs.
Avatar
Fabien LE LEZ
On Wed, 13 Oct 2004 10:04:42 +0200, Andre Heinen
:

Attention, tu retournes une référence sur un temporaire.


Oups, oui, désolé :-/


--
;-)

1 2