IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Pb std::vector dans une classe


Sujet :

Langage C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 12
    Points : 6
    Points
    6
    Par défaut Pb std::vector dans une classe
    Salut à tous,

    je veux utiliser un std::vector pour créer un tableau 2D de manière dynamique en passant en paramètre la taille du tableau au constructeur.

    voici ma classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    #include <vector>
     
    class test{
     
    public:
     
    	std::vector< std::vector<int> > Tab_2D;
     
    public:
     
    	test(int size_tab){ 
            Tab_2D.resize(size_tab,std::vector<int>(size_tab,0));
    	}
     
    };
    dans le main j'instancie une element de la classe test. la compilation fonctionne.
    ----------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <vector>
    #include "test.h"
    #include <stdio.h>
     
    int main (int ac, char *av[])
    {
    int taille=2;
    test Tab1(taille);
     
    while(1){};
     
    return 0;
    }
    ----------
    mais dès que j'ajoute la boucle d'affichage propore aux std::vector, ben j'ai l'erreur suivante.

    (code d'affichage)
    -----
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(unsigned int i(0);i<Tab1.size();++i){
        for(unsigned int j(0);j<Tab1[i].size();++j)
          {
            printf("%d\n",Tab1[i][j]);
    	  }
     }
    -----

    voici l'erreur:
    ------------
    error C2676: binary '[' : 'test' does not define this operator or a conversion to a type acceptable to the predefined operator
    ------------
    (j'utilises Visual Studio C++)


    J'imagines que l'erreur vient du fait que le "." soit généralement utilisé pour accéder aux membres de la classe. une surcharge d'opérateur serait la solution? mais je ne vois pas trop comment faire...

    le problème pourrait être résolu en utilisant une boucle normale pour afficher (une double boucle for avec un printf Tab1[i][j] avec une surchage de l'opérateur [] mais je serai limitée car je ne pourrai pas utiliser toutes les fontions membres des std::vector.

    comment dopis-je faire?

    Merci d'avance.

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Déjà, je ne suis pas sur que j'utiliserais un std::vector<std::vector<> > pour rerpésenter un tableau 2D... Il existe des classes permettant de représenter des matrices qui me semble autrement plus intéressantes à l'emploi, surtout si l'idée est de représenter un tableau deux dimension "plein" et "carré"

    De plus, comme le membre tab_2D de type vector<vector<> > est privé dans la classe, il est "normal" que l'opérateur [] qui est défini pour la classe vector ne soit pas reporté sur la classe test...

    En effet, le compilateur n'a, pour l'instant, aucun moyen de savoir comment implémenter cet opérateur pour ta classe.

    Il faudrait donc, au minimum, définir l'opérateur [] pour la classe test, mais cela aura pour conséquence, si tu ne t'y prend pas correctement d'exposer le contenu d'un membre contenu dans ta classe (en l'occurrence, le std::vecto<> contenu dans tab_2D, ce qui ne me semble pas être la meilleur solution.

    Au final, l'idéal est, sans doute, de ne pas utiliser l'opérateur [], mais de définir un comportement particulier (par exemple ceill(line, col) qui renverra tout de suite... la valeur se trouvant en lign / colonne
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Salut,

    Citation Envoyé par koala01 Voir le message
    Salut,

    Déjà, je ne suis pas sur que j'utiliserais un std::vector<std::vector<> > pour rerpésenter un tableau 2D... Il existe des classes permettant de représenter des matrices qui me semble autrement plus intéressantes à l'emploi, surtout si l'idée est de représenter un tableau deux dimension "plein" et "carré"

    De plus, comme le membre tab_2D de type vector<vector<> > est privé dans la classe, il est "normal" que l'opérateur [] qui est défini pour la classe vector ne soit pas reporté sur la classe test...

    En effet, le compilateur n'a, pour l'instant, aucun moyen de savoir comment implémenter cet opérateur pour ta classe.

    Il faudrait donc, au minimum, définir l'opérateur [] pour la classe test, mais cela aura pour conséquence, si tu ne t'y prend pas correctement d'exposer le contenu d'un membre contenu dans ta classe (en l'occurrence, le std::vecto<> contenu dans tab_2D, ce qui ne me semble pas être la meilleur solution.

    Au final, l'idéal est, sans doute, de ne pas utiliser l'opérateur [], mais de définir un comportement particulier (par exemple ceill(line, col) qui renverra tout de suite... la valeur se trouvant en lign / colonne


    merci pour ta réponsekoala01, pourrais-tu stp me dire quels sont ces classes qui permettent de spécifier des matrices? (je suis novice en c++ et ne maitrise donc pas bien le langage et ses possibilités)
    est-ce que ces classes permettent de générer des tableaux paramètrables dynamiquement? j'ai pnsé aux std::vector pour cela et ausi parce qu'ils offrent de fonctions membresqui facilitent l'accès aux elements de la matrice générée. si tu pouvais me donner des pistes pour m'aider à savoir ce qui convient le mieux à mes besoins je t'en serai strès reconnaissante.

    merci d'avance!

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Au pire, tu peux tout à fait envisager de travailler sur une classe strictement personnelle vite faite, si, de fait, tu dois travailler avec un tableau 2D plein (dans lequel le nombre de colone est identique dans chaque ligne)...

    Qu'il te suffise de penser que, si tu as N lignes et M colonnes, tu peux travailler avec un tableau 1D contenant... N*M éléments, que dés lors, tu pourrait accéder à la colonne C de la ligne L, grace à la formule L*M+C

    Ta classe "Tableau2D" pourrait donc se présenter sous la forme vite faite et "en directe" de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class Tableau2D
    {
        public: 
            Tableau2D(unsigned int l, unsigned int c):ligne_(l),
                      colonne_(c),
                      tab_(l*c)
            {
            }
            int value(unsigned int l, unsigned int c) const
           {
                return tab_[(l-1)*colonne_+(c-1)]; //prend en compte que l'index de début est 0 et non 1 ;)
           }
           void setValue(unsigned int l, unsigned int c, int v)
           {
                tab_[(l-1)*colonne_+(c-1)]=v;
           }
        private:
            unsigned int ligne_; // le nombre de lignes du tableau
            unsigned int colonne_; // le nombre de colonnes du tableau
            std::vector<int> tab_; // le tableau en lui même
    };
    Maintenant, pour te donner le nom de bibliothèque implémentant une classe matrice, il faudrait savoir quels sont tes besoins, mais les noms qui viennent rapidement à l'esprit sont boost.uBLAS ou boost.multiarray...

    Mais il y en a d'autres
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Au pire, tu peux tout à fait envisager de travailler sur une classe strictement personnelle vite faite, si, de fait, tu dois travailler avec un tableau 2D plein (dans lequel le nombre de colone est identique dans chaque ligne)...

    Qu'il te suffise de penser que, si tu as N lignes et M colonnes, tu peux travailler avec un tableau 1D contenant... N*M éléments, que dés lors, tu pourrait accéder à la colonne C de la ligne L, grace à la formule L*M+C

    Ta classe "Tableau2D" pourrait donc se présenter sous la forme vite faite et "en directe" de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class Tableau2D
    {
        public: 
            Tableau2D(unsigned int l, unsigned int c):ligne_(l),
                      colonne_(c),
                      tab_(l*c)
            {
            }
            int value(unsigned int l, unsigned int c) const
           {
                return tab_[(l-1)*colonne_+(c-1)]; //prend en compte que l'index de début est 0 et non 1 ;)
           }
           void setValue(unsigned int l, unsigned int c, int v)
           {
                tab_[(l-1)*colonne_+(c-1)]=v;
           }
        private:
            unsigned int ligne_; // le nombre de lignes du tableau
            unsigned int colonne_; // le nombre de colonnes du tableau
            std::vector<int> tab_; // le tableau en lui même
    };
    Maintenant, pour te donner le nom de bibliothèque implémentant une classe matrice, il faudrait savoir quels sont tes besoins, mais les noms qui viennent rapidement à l'esprit sont boost.uBLAS ou boost.multiarray...

    Mais il y en a d'autres
    Salut,

    encore une fois un grand merci à toi pour toutes ces infos. juste une question, si j'utilise cette classe (celle que tu as défini) est-ce que je pourrai facilement modifier le contenu de mon tableau? mon tableau contiendra des données qui changeront à chaque nouveau traitement. dois-je ajouter une fonction membre pour accéder au contenu?

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Tant que tu reste dans la limite du nombre de ligne et de colonne indiqué lorsque tu déclarer une variable du type de cette classe, tu peux définir la valeur de la cellule avec la fonction membre setValue...

    Maintenant, comme je l'ai déjà dit, il faut voir l'usage que tu souhaites faire de ce tableau 2D...

    Peut-être cette classe n'est-elle pas adaptée à tes besoins
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Tant que tu reste dans la limite du nombre de ligne et de colonne indiqué lorsque tu déclarer une variable du type de cette classe, tu peux définir la valeur de la cellule avec la fonction membre setValue...

    Maintenant, comme je l'ai déjà dit, il faut voir l'usage que tu souhaites faire de ce tableau 2D...

    Peut-être cette classe n'est-elle pas adaptée à tes besoins
    Salut,

    j'avais pas vu la fonction setValue (j'ai parcouru la classe assez vite!)

    en termes de performance, quelle solution serait la meilleure, utiliser un std::vector 2D (ce que j'avais fait au début) où la classe que t'as défini, ou bien encore une classe avec allocation dynamique comme cela (ci-dessous) ou carrément la librairie boost pour matrices???
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    #include <stdio.h>
     
     
    class test{
    public:
      int** tab;
    public:
    	test();
    	test(int size){ 
    		tab= new int*[size];
    		for (int i = 0; i < size; i++)
            tab[i] = new int[size];	
    	}
    public:
    	int get(int i,int j){
    	return tab[i][j];
    	}
    public:
    	void set(int i,int j,int val){
    	 tab[i][j]=val;
    	}
    };

    pour mes besoins, ben c'est d'avoir une matrice paramétrable (qui sera carrée tout le temps à priori) et qui contiendra des valeurs de pixels (c'est pour faire du traitement d'images). à partir du format de l'image, disons N*N, je fractionnerai mon image en plusieurs matrices de taille (m*m, m<N) (m sera paramétrable) et chaque matrice sera utilisée pour faire certains traitements (moyenne des pixels,...). donc au vu de tout cela, en sachant que ce n'est pas vraiement du C++ que je fais mais du systemC (c'est une classe de C++ pour la description matérielle qui permettra de paralléliser les traitements,...), quelle modélisation de matrice m'offrira le plus de performance (vitesse d'exécution ) mais aussi de faciliter de modélisation des traitements (par exemple si j'utilise une classe que je défini moi-même, si je dois multiplier la valeur de mes pixels par une constante, je dois écrire une fonction qui le fasse alors qu'avec la librairie boost il y a déjà une fonction toute prête et qui sera donc plus performante non?)

    merci d'avance pour la réponse!

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Pour info: Tu n'es absolument pas obligé de rajouter le spécificateur de visibilité public: (ni aucun autre, d'ailleurs) devant chaque fonction publique: un spécificateur de visibilité (private: / protected: / public: ) s'applique, en effet "jusqu'à instruction contraire", c'est à dire, jusqu'à ce que l'on croise un spécificateur différent

    Pour le reste:

    Une chose est sure, j'éviterais d'utiliser l'allocation dynamique de la mémoire manuelle, ne serait-ce que parce que la classe que tu propose présente déjà une fantastique fuite mémoire

    La classe que je présente n'est peut être pas forcément adaptée à l'obtention d'une "sous matrice", dans le sens où il est difficile d'obtenir "d'une traite" les trois premiers pixels des trois premières lignes (par exemple). Par contre, elle fournit un acces en temps constant à n'importe quel pixel pris séparément

    Je ne la connais que de nom, mais, peut être devrais tu t'intéresser un peu à boost.GIL, qui est une bibliothèque permettant de gérer les différents formats images... Elle présente peut être quelques trucs qui t'intéresseront ... Mais je ne peux absolument pas te renseigner sur ses performances à l'exécution

    Peut être boost.MultiArray sera-t-il plus adapté

    Peut être quelqu'un d'autre saura-t-il mieux répondre sur ce point, car je t'avouerai que je n'ai personnellement aucune idée
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Pour info: Tu n'es absolument pas obligé de rajouter le spécificateur de visibilité public: (ni aucun autre, d'ailleurs) devant chaque fonction publique: un spécificateur de visibilité (private: / protected: / public: ) s'applique, en effet "jusqu'à instruction contraire", c'est à dire, jusqu'à ce que l'on croise un spécificateur différent

    Pour le reste:

    Une chose est sure, j'éviterais d'utiliser l'allocation dynamique de la mémoire manuelle, ne serait-ce que parce que la classe que tu propose présente déjà une fantastique fuite mémoire

    La classe que je présente n'est peut être pas forcément adaptée à l'obtention d'une "sous matrice", dans le sens où il est difficile d'obtenir "d'une traite" les trois premiers pixels des trois premières lignes (par exemple). Par contre, elle fournit un acces en temps constant à n'importe quel pixel pris séparément

    Je ne la connais que de nom, mais, peut être devrais tu t'intéresser un peu à boost.GIL, qui est une bibliothèque permettant de gérer les différents formats images... Elle présente peut être quelques trucs qui t'intéresseront ... Mais je ne peux absolument pas te renseigner sur ses performances à l'exécution

    Peut être boost.MultiArray sera-t-il plus adapté

    Peut être quelqu'un d'autre saura-t-il mieux répondre sur ce point, car je t'avouerai que je n'ai personnellement aucune idée
    merci pour ta réponse.

    donc l'allocation dynamique comme je l'ai faite est à éviter le plus possible. ok. donc le premier code que j'avais mis dans ce post, celui des std::vector 2D est bien plus préférerable que celui des "int**" ou de la classe "Tableau2D" (car elle ne me permettra pas d'accéder à plusieurs pixels en même temps ce qui fait que je dois utiliser des variables intermédiaires pour stocker mes données avant de pouvoir faire une moyenne de pixels par exemple?) c'est bien cela?

    je vais essayer de voir ce que sont les bibliothèques dont tu m'as parlé, merci encore.

    Si quelqu'un d'autre à des conseils pour moi, qu'il n'hésites pas

Discussions similaires

  1. initialisation/suppression d'un vector dans une classe
    Par mokochan dans le forum Débuter
    Réponses: 3
    Dernier message: 19/12/2014, 11h50
  2. Vector dans une classe qui vient de Java
    Par JeanNoel53 dans le forum C++
    Réponses: 7
    Dernier message: 13/07/2010, 16h41
  3. Réponses: 9
    Dernier message: 12/07/2010, 14h25
  4. vector dans une class
    Par squale69 dans le forum C++
    Réponses: 7
    Dernier message: 11/04/2008, 20h05
  5. Récupérer un Vector d'une classe dans une autre
    Par javamax dans le forum Langage
    Réponses: 2
    Dernier message: 22/10/2006, 13h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo