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

SL & STL C++ Discussion :

Changer le type des éléments d'un container


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Par défaut Changer le type des éléments d'un container
    Bonjour,

    Je dois utiliser un container (dans mon cas un vecteur) comme membre d'une classe, et il faudrait que le type des éléments puisse varier. Par exemple j'ai mon vecteur qui contient des int, et je dois le vider pour le remplir avec des float. Je pense faire un pointer vers un vecteur, et à chaque fois que je dois changer le type je fais un delete / new, pensez-vous que ce soit la meilleure manière?

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    ça ne marchera pas

    std::vector<int> et std::vector<float> sont deux types différents, tu ne peux pas faire de pointeurs compatibles avec l'un ou l'autre.

    Est-ce que tu peux expliquer un peu pourquoi tu as besoin de faire ça? ( vider puis re-remplir avec un autre type? ).

  3. #3
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour

    Une solution serait de définir une classe de stockage au courant de son état (il doit y avoir un design pattern qui existe pour cela), un peu dans le genre :
    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
    24
    25
    26
    27
    28
    29
     
    class intOUfloat{
       int m_i;
       float m_f;
       static bool m_bState; // true pour entier, false pour float
     
    public:
       static void setState(bool b){
          m_bState = b;
       }
     
       void operator = (float f){
          if(m_bState)
             throw "Error not float";
          else
             m_f = f; 
       }
     
       void operator = (int i){
          if(!m_bState)
             throw "Error not int";
          else
             m_i = i; 
       }
    };
     
    // et après
     
    vector<intOUfloat> v;
    Mais on tourne un peu autour du pot : si dans le programme les float ne sont jamais utilisés, c'est autant d'espace mémoire perdu.

  4. #4
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Citation Envoyé par Cheps Voir le message
    Bonjour,

    Je dois utiliser un container (dans mon cas un vecteur) comme membre d'une classe, et il faudrait que le type des éléments puisse varier. Par exemple j'ai mon vecteur qui contient des int, et je dois le vider pour le remplir avec des float. Je pense faire un pointer vers un vecteur, et à chaque fois que je dois changer le type je fais un delete / new, pensez-vous que ce soit la meilleure manière?
    Bonjour,

    A proprement parler, ce que tu veux faire n'est pas impossible.

    Mais si tu as besoin de faire ce que tu demandes, c'est probablement que tu as mal compris quelque chose ou mal conçu quelque chose.

    Explique plus en détail ton problème, et tu trouveras ici des gens qui te proposeront une "meilleure" solution, c'est à dire une solution avec moins de risques d'erreur et plus facile à maintenir.

    Ce sera probablement l'occasion d'en apprendre plus sur la philosophie de la conception objet.

    Bonne journée.

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Par défaut
    Bon je vais essayer de résumer le contexte. J'ai une application graphique, et j'ai des données de différents types (int, float, double). J'ai un composant qui doit afficher des graphes selon ces données. Ce composant a une méthode setValues(vector v) qui reçoit les valeurs à afficher (mon composant doit évidemment stocker les données pour pouvoir les réafficher en cas de refresh). Je pourrais convertir les int et les float en double pour les passer en paramètre mais je préfère garder leur type de base si possible.

    Donc je pourrais créer un composant différent pour chaque type de données à afficher. Ou bien je pourrais créer un container abstrait, avec une classe fille pour chaque type de données. Mais je pensais qu'avec la STL je pourrais me faciliter un peu la vie.

    J'espère que vous avez tout compris
    Des idées?

  6. #6
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Pardon de revenir là-dessus aussi tard. C'est la dure loi des forums.

    C'est peut-être trop tard pour t'aider, mais je vais quand même donner une réponse au cas où.

    On va supposer que tu as une bonne raison de ne pas vouloir tout convertir en double. Personnellement, je ne suis pas partisan de l'idée de complexifier un modèle de données juste pour se faire plaisir. Il ne faut pas oublier que la complexité gratuite est chère à entretenir.

    Si j'étais toi, je ferais bel et bien 3 objets distincts qui héritent du même objet parent, en ne spécialisant que le minimum. En particulier, il serait probablement bon que tes trois objets, même s'ils gardent leurs valeurs chacun dans son format interne (int, float, double), communiquent quand même avec la fonction qui génère les graphe tous dans le même format. Par exemple, en lui donnant juste les valeurs converties dans la précision dont tu as besoin pour les afficher (appelons cela Pixel).

    Comme à chaque fois que tu fais 3 objets presque identique, il te faudra bien sur utiliser les templates afin de faciliter l'évolution de ton code.

    Je choisirais donc quelque chose comme ceci :
    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
    24
    25
    class GraphMaker_Base
    {
    public :
    	void display();
    	typedef std::vector<int> ValuesInPixels;
     
    protected :
    	virtual const ValuesInPixels& getValuesFormatedInPixel(echelle)=0;
    	void initGraph();
    	void createGrid(...);
    	void createLegend(...);
    	void createCourbeWithThisValuesInPixel(const ValuesInPixels& values);
    };
     
    template<typename T>
    class GraphMaker : public GraphMaker_Base
    {
    protected :
    	typedef std::vector<T> ValuesInInternalFormat;
    	ValuesInInternalFormat values;
    	void setValues(ValuesInInternalFormat v);
     
    protected :
    	virtual const ValuesInPixels& getValuesFormatedInPixel(echelle);
    };
    Je ne t'apprends donc pas grand chose et j'en suis désolé.

  7. #7
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Addendum :

    Prenons un exemple,
    Admettons que tu traces tes graphes sur une hauteur de 300 pixels.

    Admettons que tu aie deux jeux de valeurs :
    [0 1 2 3 4 5]
    et
    [2.5 5.0 7.5 10.0]

    Tu aurais deux objets
    un de type GraphMaker<int> qui contient [0 1 2 3 4 5]
    un de type GraphMaker<float> qui contient [2.5 5.0 7.5 10.0]

    Et l'appel de getValuesFormatedInPixel(300) sur chacun de ces deux objets renverrait :
    - [0 60 120 180 240 300] pour le premier
    - [75 150 225 300] pour le second

    Je ne sais pas si c'est plus clair ?

  8. #8
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    A défaut de pouvoir changer le type d'élément des vecteurs, on peut tricher en utilisant un vecteur de boost::any.Ainsi, pour changer le type d'élément, il suffira de vider ton vecteur et d'ajouter les nouveaux.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

Discussions similaires

  1. Réponses: 7
    Dernier message: 11/10/2011, 17h54
  2. Jsdoc, type des éléments d'un Array
    Par dukej dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 28/01/2011, 00h05
  3. Changer l'ordre des éléments d'une JList avec la souris
    Par rafalsh dans le forum Composants
    Réponses: 0
    Dernier message: 02/07/2009, 20h13
  4. [XSLT] Changer le nom des éléments...
    Par kobe dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 14/11/2005, 11h00
  5. [CSS]Changer l'interligne des éléments d'une liste à puces
    Par khany dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 21/03/2005, 13h57

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