Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 06/11/2008, à 19:20

rniamo

c++ et [][] et autres [résolu]

bonjour,

est-il possible de définir l'opérateur [][] (tableau 2D) ?

Dernière modification par rniamo (Le 08/11/2008, à 20:17)


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#2 Le 06/11/2008, à 19:41

valAa

Re : c++ et [][] et autres [résolu]

Je dis peut-être des conneries, mais pour moi l'opérateur [][] n'existe pas.

Une fois défini correctement l'opérateur [], ça roule...
exemple : x[y][z].

ça correspond en fait à faire x[y], et si cela te retourne un objet (disons w) pour lequel a été défini [], faire w[z]

donc si [] est défini pour x, et pour w (=x[y]), alors ça roule...

J'ai bon ? c'est pas clair ? big_smile

Dernière modification par valAa (Le 06/11/2008, à 19:41)

Hors ligne

#3 Le 06/11/2008, à 19:53

rniamo

Re : c++ et [][] et autres [résolu]

je veux que mon objet représente un tableau 2D donc qu'il soit utilisable avec [][] directement.


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#4 Le 06/11/2008, à 21:07

rniamo

Re : c++ et [][] et autres [résolu]

il n'est pas possible d'ajouter des opérateurs ?

sinon j'ai quelques soucis :

template<typename Tn>
Matrice<Tn>::Matrice(int lignes, int colonnes, const Tn **tableauValeur) throw(Exception) {
	if (!tableauValeur)
		throw Exception("Init. array error (array==NULL).");
		
	try {
		MATtableau.resize(lignes);
		for(unsigned int iBoucleLigne=0;iBoucleLigne<MATtableau.size();iBoucleLigne++) {
			MATtableau[iBoucleLigne].resize(colonnes);
			for(unsigned int iBoucleColonne=0;iBoucleColonne<MATtableau[iBoucleLigne].size();iBoucleColonne++)
				MATtableau[iBoucleLigne][iBoucleColonne]=tableauValeur[iBoucleLigne][iBoucleColonne];
		}
	}
	catch(std::bad_alloc& ba) {
		throw Exception("Memory error.");
	}
}

int **test() {
	int **init=new int*[3];
	for(int i=0;i<3;i++) {
		init[i]=new int[5];
		for(int j=0;j<5;j++)
			init[i][j]=i+j;
	}
	return init;
}

int main() {
	try {
		int **init=test();
		Matrice<int> MATtab(3,5,init);
	}
	catch(const Exception& ex) {
		std::cout << ex.getMessage() << std::endl;
	}
	
	return EXIT_SUCCESS;
}

erreur :

main.cc: In function ‘int main()’:
main.cc:23: erreur: no matching function for call to ‘Matrice<int>::Matrice(int, int, int**&)’
Matrice.cc:36: note: candidats sont: Matrice<Tn>::Matrice(const Matrice<Tn>&) [with Tn = int]
Matrice.cc:18: note:                 Matrice<Tn>::Matrice(int, int, const Tn**) [with Tn = int]
Matrice.cc:2: note:                 Matrice<Tn>::Matrice(int, int, const Tn&) [with Tn = int] <near match>

edit : le problème vient de const, je ne peux pas utiliser une méthode avec un paramètre non const si celui-ci est défini const ? ( const int **init=const_cast<const int**>(test()); marche)

Dernière modification par rniamo (Le 06/11/2008, à 21:16)


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#5 Le 06/11/2008, à 21:36

tiky

Re : c++ et [][] et autres [résolu]

Une méthode constante en C++ est une méthode dont le pointeur this sur l'objet courant est lui-même constant. Il n'est donc pas possible de modifier les données de l'objet mais tu peux tout à fait modifier les paramètres. Ce sont d'ailleurs les seules méthodes qui peuvent être appelées par un objet constant.


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#6 Le 06/11/2008, à 21:44

tiky

Re : c++ et [][] et autres [résolu]

#include <iostream>

class Foo
{
    public:
	void foobar( int * data ) const
	{
	    (*data)++;
	    std::cout << *data << std::endl;
	}
    private:
	int m_data;
};

int main( void )
{
    int data = 23;
    Foo f;
    f.foobar( &data );
    std::cout << data << std::endl;
    return 0;
}

Tu peux le constater, je modifie bien la valeur de la variable data dans la méthode foobar constante de la classe Foo, par contre je ne suis pas autorisé à modifier la variable membre m_data dans cette méthode.

Dernière modification par tiky (Le 06/11/2008, à 21:45)


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#7 Le 06/11/2008, à 22:04

tiky

Re : c++ et [][] et autres [résolu]

Ton problème de constante est expliqué ici: http://fr.wikibooks.org/wiki/Programmation_C-C%2B%2B/R%C3%A9f%C3%A9rences_et_pointeurs_constants_et_volatiles

Un exemple où tu diminues pas la constance:

#include <iostream>

class Foo
{
    public:
	void foobar( const int ** data, size_t size ) const
	{
	    unsigned int i;
	    for( i = 0; i < size; i++ )
		std::cout << (*data)[i] << std::endl;
	}
    private:
	int m_data;
};

int main( void )
{
    size_t size = 4;
    int * data = new int[ size ];
    unsigned int i;
    for( i = 0; i < size; i++ )
    {
	*(data + i ) = i;
    }

    Foo f;
    const int * const_data = data;
    f.foobar( &const_data, size );
    delete[] data;

    return 0;
}

Dernière modification par tiky (Le 06/11/2008, à 22:18)


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#8 Le 06/11/2008, à 22:27

valAa

Re : c++ et [][] et autres [résolu]

rniamo a écrit :

je veux que mon objet représente un tableau 2D donc qu'il soit utilisable avec [][] directement.

j'ai pas dit le contraire...
tu as essayé ? ça ne marche pas ?

Hors ligne

#9 Le 06/11/2008, à 22:28

rniamo

Re : c++ et [][] et autres [résolu]

j'ai pas bien saisi, moi je veux juste pouvoir passer en argument un const T** ou T** (sans faire deux fonctions si possibles).

Enfin je n'arrive pas à utiliser un tableau définit comme suit :

Type *nom[taille]={{v1,v2...},{...},...};


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#10 Le 06/11/2008, à 22:39

tiky

Re : c++ et [][] et autres [résolu]

Tu ne peux pas convertir explicitement un T ** en const T ** c'est une opération illégale comme je viens de te le dire.

Ton tableau int ** dans ton main autorise la modification de l'entier.
Imaginons que A soit int * et B soit int **.
On a: B -> A -> int.
Lorsque tu demandes à convertir T** en const T**, le compilateur va créer un nouveau pointeur C de type const T**, on obtient le schéma:
C -> A -> int.
Or A n'a pas changé ! c'est le même pointeur et il autorise toujours la modification sur l'entier vers lequel il pointe. Autrement dit si le compilateur autorisé une telle conversion, il suffirait de déréférencer le pointeur C pour obtenir dans ta fonction un pointeur vers l'entier non constant !


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#11 Le 06/11/2008, à 22:45

rniamo

Re : c++ et [][] et autres [résolu]

oui mais c'est pas du tout possible en argument de dire qu'on accepte const ou pas ?(sinon ça fait deux fois la même fonction)


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#12 Le 06/11/2008, à 22:49

tiky

Re : c++ et [][] et autres [résolu]

Lorsque tu fais un table[x][y], ça revient à faire un (table[x])[y], il suffit de surcharger l'opérateur [], et cela même s'il s'agit d'un tableau multidimensionnel.

#include <iostream>
#include <cstring>

class Foo
{
    public:
	Foo( void )
	{
	    memset( m_table, 0, 5*5*sizeof( int ) );
	}

	int * operator[]( int i )
	{
	    return m_table[i];
	}
    private:
	int m_table[5][5];
};

int main( void )
{
    Foo f;
    std::cout << f[2][3] << std::endl;
    return 0;
}

Dernière modification par tiky (Le 06/11/2008, à 22:51)


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#13 Le 06/11/2008, à 22:57

tiky

Re : c++ et [][] et autres [résolu]

Utilise const Tn * const *.


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#14 Le 06/11/2008, à 23:06

rniamo

Re : c++ et [][] et autres [résolu]

pas mal le coup de surcharge de [], je n'y étais pas. Tu peux expliquer le const Tn* const * stp ?

edit : si mon  tableau est défini comme ça std::vector< std::vector<Tn> >, comment je fait pour surcharger [] ?
edit 2 : j'ai surchargé () ... mais je n'arrive pas à surcharger [], je renvoie un  std::vector< std::vector<Tn> >::iterator.
edit 3 : juste une confirmation les surcharge d'opérateurs ne sont pas symétriques, c'est ça ?

Dernière modification par rniamo (Le 06/11/2008, à 23:25)


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#15 Le 06/11/2008, à 23:38

tiky

Re : c++ et [][] et autres [résolu]

rniamo a écrit :

pas mal le coup de surcharge de [], je n'y étais pas. Tu peux expliquer le const Tn* const * stp ?

edit : si mon  tableau est défini comme ça std::vector< std::vector<Tn> >, comment je fait pour surcharger [] ?
edit 2 : j'ai surchargé () ... mais je n'arrive pas à surcharger [], je renvoie un  std::vector< std::vector<Tn> >::iterator.
edit 3 : juste une confirmation les surcharge d'opérateurs ne sont pas symétriques, c'est ça ?

edit: je dirais qu'il faut simplement retourner le n ème std::vector.
Je ne sais pas ce que tu entends pas symétrique.


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#16 Le 06/11/2008, à 23:48

tiky

Re : c++ et [][] et autres [résolu]

const Tn* const * est un pointeur sur un pointeur constant sur un élément Tn constant.
On peut voir le type de la manière suivante:

(const Tn * const ) *

Note: const agit toujours sur l'élément qui le précède.

En rendant le pointeur constant tu interdis l'opération suivante:

const Tn * const * table;
Tn * el = *table.

Par conséquent, il n'est plus possible de contourner le const sur Tn.
Note: Je t'avoue que je suis pas tellement sûr, en tout cas ça fonctionne.

Dernière modification par tiky (Le 06/11/2008, à 23:52)


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#17 Le 07/11/2008, à 14:02

rniamo

Re : c++ et [][] et autres [résolu]

ça fonctionne mais je ne comprends pas pourquoi on peut mettre une instance constante ou pas ... je reregarderais const quand j'aurais 2s. Merci en tout cas.

Pour les vectors mon problème est qu'il ne veut pas de l'iterator ...


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#18 Le 07/11/2008, à 14:48

nicolas66

Re : c++ et [][] et autres [résolu]

Question stupide : pourquoi ne pas stocker ta matrice dans un simple pointeur ?


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#19 Le 07/11/2008, à 14:57

rniamo

Re : c++ et [][] et autres [résolu]

Pour plusieurs raisons :

1) pour tester les templates
2) M3=M1+M2 ou M3=M1/M2 etc... c'est plus agréable wink


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#20 Le 07/11/2008, à 17:09

nicolas66

Re : c++ et [][] et autres [résolu]

Non mais je pensais plutôt à ça :

template<class T> class Matrix
{
     private :
        T *m_Data;
        int m_NbRows, m_NbCols;

     public :
        Matrix( const int NbRows, const int NbCols, const T Value = T() ) : m_NbRows(NbRows), m_NbCols(NbCols), m_Data(new T[NbRows*NbCols]){ Fill(Value); }
        ~Matrix(){ delete [] m_Data; m_Data = NULL; }
	int Rows() const{ return m_NbRows; }
	int Cols() const{ return m_NbCols; }
        void Fill( const T Value )
        {
                for( int k=0; k<m_NbRows*m_NbCols; k++ )
                        m_Data[k] = Value;
        }
	T & operator () ( const int i, const int j ){ return m_Data[j * m_NbRows + i]; }
	T   operator () ( const int i, const int j ) const{ return m_Data[j * m_NbRows + i]; }
	friend std::ostream & operator << ( std::ostream & out, const Matrix<T> & Matrix )
	{
		for( int j(0); j<Matrix.Rows(); j++ )
		{
			for( int i(0); i<Matrix.Cols(); i++ )
				out << Matrix(i, j) << " ";
			out << std::endl;
		}

		return out;
	}
};

Perso, ca me paraît plus simple que de passer par des `std::vector' et ça ne t'empêche pas d'implémenter des opérateurs matriciels smile

EDIT : une partie de la FAQ Lite Fr évoque le problème de l'opérateur d'indexation pour les matrices.

Dernière modification par nicolas66 (Le 07/11/2008, à 18:25)


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#21 Le 07/11/2008, à 23:31

rniamo

Re : c++ et [][] et autres [résolu]

L'avantage des std::vector est que je peux redimmensionner ma matrice... et c'est pour apprendre


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#22 Le 08/11/2008, à 00:10

nicolas66

Re : c++ et [][] et autres [résolu]

Pas convaincu. A mon avis t'apprendras plus sans utiliser les `std::vector' dans cet exemple. Pis si tes matrices contiennent beaucoup de 0, va voir du côté des matrices creuses, c'est nettement plus fun à implémenter tongue


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#23 Le 08/11/2008, à 20:16

rniamo

Re : c++ et [][] et autres [résolu]

Mes matrices ont une taille < 10² et je veux apprendre un peu les containers de la stl.

Et puis les matrices creuses ... j'ai pas beaucoup de 0 et il y a plus fun  wink (éléments finis inside wink)


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#24 Le 08/11/2008, à 20:27

nicolas66

Re : c++ et [][] et autres [résolu]

je veux apprendre un peu les containers de la stl

L'un n'empêche pas l'autre. Tu peux coder tes matrices avec des pointeurs et apprendre les conteneurs de la STL en // wink


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#25 Le 08/11/2008, à 20:39

rniamo

Re : c++ et [][] et autres [résolu]

oui c'est sût mais la je faisait d'une pierre deux coups wink.


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne