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

 C++ Discussion :

Passer un tableau (dont on ne connait pas la taille à l'avance) en attribut d'une classe


Sujet :

C++

  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur essais
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur essais
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Par défaut Passer un tableau (dont on ne connait pas la taille à l'avance) en attribut d'une classe
    Bonjour à toutes et à tous

    Je viens de débuter dans le C++, et pour m'entrainer je souhaite appliquer la théorie dans un excercice utile pour mon travail.

    Je souhaiterai tout simplement créer une classe "mesures", dans laquelle l'utilisateur peut passer un tableau de mesures donc on ne connait pas la taille par avance.
    Certains objets créer auront donc un tableau de taille 50, d'autres de taille 80, etc...

    Voici le header que j'ai créé:

    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
    #ifndef MEASUREMENTS_H_INCLUDED
    #define MEASUREMENTS_H_INCLUDED
     
    class Measurements
    {
        public:
     
        Measurements();
        Measurements(int sizeTab, std::string names[sizeTab], std::string units[sizeTab], double values[sizeTab]);
     
        private:
     
        int m_sizeTab;
        std::string m_names[m_sizeTab];
        std::string m_units[m_sizeTab];
        double m_values[m_sizeTab];
    };
     
    #endif // MEASUREMENTS_H_INCLUDED
    Et voici le cpp:

    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
    #include <iostream>
    #include <string>
    #include "Measurements.h"
     
    using namespace std;
     
    //Object methods
     
    Measurements::Measurements()
    {
        m_sizeTab = 1;
        m_names[m_sizeTab] = {"DEFAUT"};
        m_units[m_sizeTab] = {"DEFAUT"};
        m_values[m_sizeTab] = {0};
    }
     
    Measurements::Measurements(int const sizeTab, std::string names[sizeTab], std::string units[sizeTab], double values[sizeTab]):
        m_sizeTab(sizeTab), m_names(names), m_units(units), m_values(values)
    {
    }
    Je voudrais savoir pourquoi le programme n'abouti pas, et quelle logique m'a échappée.

    Merci bien !

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Moi, je voudrais savoir pourquoi ça compile. Le C++ n'est pas censé supporter les Variable-Length Arrays du C99.
    Par contre, à partir de C++14, on peut utiliser std::dynarray.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur essais
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur essais
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Moi, je voudrais savoir pourquoi ça compile. Le C++ n'est pas censé supporter les Variable-Length Arrays du C99.
    Par contre, à partir de C++14, on peut utiliser std::dynarray.
    Je suis pas sur de bien comprendre.
    Ce n'est pas vraiment un tableau de taille variable qui sera utiliser. Sinon j'aurais utiliser "vector".
    C'est un tableau statique, sauf que dans mon constructeur je ne peux pas déterminer une taille car elle peut varier selon l'objet créé.

    Si ma réponse est à côté de votre explication, j'en suis désolé et du coup je n'ai pas bien compris.

    A mon niveau, j'ai appris que pour créer un tableaux statique, il fallait procéder de la manière suivante :
    TYPE NOM[TAILLE];
    Par exemple :
    Je souhaiterai utiliser des tableaux statiques, mais dont on ne connait pas la taille par avance.
    Sauf que je n'arrive pas à l'appliquer aux classes dans ma surcharge de constructeur.

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Citation Envoyé par Joseldsm Voir le message
    A mon niveau, j'ai appris que pour créer un tableaux statique, il fallait procéder de la manière suivante :
    TYPE NOM[TAILLE];
    Par exemple :
    Je souhaiterai utiliser des tableaux statiques, mais dont on ne connait pas la taille par avance.
    Ça n'existe pas en C++.
    Si tu n'utilises pas un vector ou un dynarray, alors la taille de tableau doit être connue à la compilation.

    Par contre, ça peut être un paramètre d'une classe template. Mais ça veut dire qu'à chaque taille correspondra une "classe" différente.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur essais
    Inscrit en
    Juillet 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur essais
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2013
    Messages : 41
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Ça n'existe pas en C++.
    Si tu n'utilises pas un vector ou un dynarray, alors la taille de tableau doit être connue à la compilation.

    Par contre, ça peut être un paramètre d'une classe template. Mais ça veut dire qu'à chaque taille correspondra une "classe" différente.
    Très bien, je vais tenter ma chance avec un vector alors, merci bien pour l'aide !

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Déjà, vu que le nom et le score et les unités sont trois éléments qui sont fait pour aller systématiquement ensembles (chaque fois que tu voudras afficher un nom, tu voudras aussi afficher le score et les unités qui y sont associés), tu devrais créer une structure qui regroupe ces informations.

    Cela pourrait prendre une forme aussi simple que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct ScoreInfo{
        std::string name;
        std::string units;
        double value;
    };
    mais cela te simplifiera énormément la vie

    Ensuite, j'ai envie de dire que, par défaut, ta notion de mesure est une notion qui ne contient jamais aucune donnée quand elle est créée: elle est créée vide, et remplie "au fur et à mesure" de son utilisation et tu n'as donc -- a priori -- aucune raison de vouloir fournir des informations dans le constructeur

    Cependant, si tu n'es pas tout à fait d'accord avec mon analyse (après tout, je ne prétend pas avoir la science infuse ) il y a deux options à considérer, chacune d'elle étant totalement indépendante de l'autre:

    La première est que tu peux souhaiter fournir des éléments "figés dans le marbre" car écrit en dur directement dans le code. La solution idéale passe donc par ce que l'on appelle une initialiser_list.

    La deuxième est que tu peux souhaiter fournir des informations qui ont été obtenues à l'exécution de ton programme (par exemple, en les lisant dans un fichier). Tu auras donc placé ces information "dans une collection quelconque" (par exemple, dans un tableau), et tu pourrais transmettre les itérateur de début et de fin sur cette collection, pour que ton ensemble soit rempli avec ces éléments.

    Enfin, il faut savoir que ce que tu essaye de faire (et qui porte le nom de VLA pour Variable Length Array) est interdit en C++: Si tu veux disposer d'un tableau d'éléments dont tu ignore le nombre lors de la compilation, le mieux est encore d'avoir recours à la classe qui est spécialement prévue à cet effet, à savoir la classe std::vector.

    Si bien qu'au final, ta classe Measurements pourrait parfaitement se limiter à un simple alias de type proche de using Measurements std::vector<ScoreInfo>; vu que, l'un dans l'autre, tu voudras sans doute pouvoir profiter de toutes les fonctionnalités proposées par la classe std::vector.

    Mais, si tu souhaites ne disposer que de certaines des opportunités de la classe std::vector, et que tu souhaites, en outre, disposer de fonctionnalités spécifiques, tu peux également envisager de créer classe normale qui prendrait sans doute alors la forme 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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    class Measurements{
    public:
        Measurements(){}
        /* pour pouvoir fournir une liste d'éléments codée en dur */
        Measurements(std::initializer_list items):items_{items}{}
        /* pour pouvoir fournir une liste d'éléments définie à l'exécution */
        template <typename ITER>
        Measurements(ITER begin, ITER end):items_{begin, end}{}
        /* pour pouvoir facilement ajouter une nouvelle valeur */
        void add(std::string const & name, std::string const & units, double value){
            items_.push_back(ScoreInfo{name, units, value});
        }
        /* quelques alias de type pour la facilité */
        using iterator = typename std::vector<ScoreInfo>::iterator;
        using const_iterator = typename std::vector<ScoreInfo>::const_iterator;
        /* les fonctions begin et end, qui nous seront utiles dans de nombreuses occasions */
        iterator begin(){
            return items_.begin();
        }
        iterator end(){
            return items_.end();
        }
        const_iterator begin() const{
            return items_.begin();
        }
        const_iterator end() const{
            return items_.end();
        }
        /* il est toujours intéressant de pouvoir déterminer le nombre d'éléments dont on dispose */
        size_t size() const{
            return items_.size();
        }
        /* peut-être voudras tu accéder aux différents éléments de manière séparée? */
        ScoreInfo & operator [](size_t index) {
            assert(index < items_.size() && "index out of bound");
            return items_[index];
        }
        ScoreInfo const & operator[](size_t index) const{
            return const_cast<Measurements *>(this)->operator[](index);
        }
        /* les autres fonctionnalités auxquelles je n'ai pas pensé */
    private:
        std::vector<ScoreInfo> items_;
    };
    De cette manière, au moins, tu ne risques pas d'aller faire des conneries en essayant de gérer la mémoire de manière dynamique
    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
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Par contre, à partir de C++14, on peut utiliser std::dynarray.
    Non, std::dynarray a été retiré du C++14 et n'est toujours pas présent en C++17.
    Dans N4140 (C++14 final draft) et dans N4659 (C++17 final draft), il n'y a aucune occurrence de "dynarray".

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Accéder à un tableau dont on ne connait pas le nom
    Par c.piette dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 06/05/2015, 07h33
  2. Réponses: 0
    Dernier message: 03/04/2014, 23h45
  3. Tableau simple dont on ne connait pas la taille
    Par Wells dans le forum VB.NET
    Réponses: 3
    Dernier message: 04/10/2007, 16h49
  4. [8051] Tableau dont on ne connaît pas la taille
    Par micro8051 dans le forum Autres architectures
    Réponses: 5
    Dernier message: 11/06/2007, 13h18
  5. [algorythmie] remplir un tableau dont on ne connait pas encore la taille
    Par d_token dans le forum Collection et Stream
    Réponses: 27
    Dernier message: 26/09/2006, 17h36

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