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 :

Instancier une classe à partir d'une variable


Sujet :

C++

  1. #21
    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
    Bon, nous allons donc de "gratter un peu le vernis" pour t'aider à comprendre...

    Qt (et attention, il y a une différence entre Qt et QT: QT c'est ce que l'on utilise pour désigner QuickTime, qui par chance, a été abandonné depuis longtemps. Qt, c'est le framework que tu utilises ) est un framework, à l'origine, développé pour permettre la mise en oeuvre d'IHM (Interfaces Homme / Machine, aussi connues sous le nom d'"interface graphique").

    Un framework, c'est un ensemble de fonctionnalités qui sont mises à ta disposition, mais que tu dois apprendre à utiliser de manière correcte. Car, si tu ne l'utilises pas de manière correcte, tu n'arriveras à rien.

    Le fait est que Qt est un framework pour le moins... envahissant: Si tu n'y prends pas garde, tu te retrouve très rapidement dans une situation dans laquelle Qt va s'imposer à tous les niveaux de ton application. Et ca, c'est pas la meilleure des choses qui soient.

    C'est même une situation particulièrement dommage, parce que Qt a justement été développé pour permettre la mise en oeuvre d'une architecture de type MVC (pour Model, View, controler) ou, pour être vraiment précis, de type MVD (pour Model, View, Delegate).

    Le principe de ces architectures est de créer une séparation claire et précise entre les données qui font partie de ton "corps de métier" (c'est ce que l'on appelle "le modèle") d'une part, ce qui permet de fournir -- par exemple à l'utilisateur -- une représentation de ces donnée (c'est ce que l'on appelle "la vue") d'autre part et, pour une troisième part ce qui permet à la vue manipuler les données métier (c'est ce que l'on appelle "le controleur" ou "le délégué").

    On s'est en effet rendu compte depuis près de vingt ans que, si l'on ne séparait pas ces trois éléments, nous finissions rapidement avec un projet monolithique, difficile à faire évoluer et, surtout, impossible à adapter -- le cas échéant -- à d'autres technologies, mais que si on sépare clairement le modèle des deux autres éléments (car il y a une certaine dépendance entre les délégués et la vue, étant donné que la vue est ce qui récupèrera les différentes entrées occasionnées par l'utilisateur), les choses deviennent tout de suite beaucoup plus simples.

    Note que ce que l'on appelle "la vue" regroupe une gamme de domaines particulièrement large, parce que nous pourrions définir n'importe quel moyen permettant à ton application de transmettre une représentation sous quelque forme que ce soit des données dont elle dispose comme faisant partie de la vue.

    C'est la raison pour laquelle Qt est composé d'autant de modules, car, si tu veux envoyer des données sur le réseau (par exemple), l'ensemble des données que tu veux transmettre peut être considéré comme une vue.

    L'idée est donc de faire en sorte que le modèle ne dépende absolument pas du framework que tu utilise pour créer ton interface graphique. Comment Hé bien, en (très) gros, en te limitant au fonctionnalités fournies par la bibliothèque standard du langage que tu utilises. En C++, ce sera (pour simplifier à l'extrême) tout ce qui se trouve dans l'espace de noms std.

    Tu n'as, en effet, absolument pas besoin de plus que ce qui se trouve dans l'espace de noms std pour pouvoir lire un fichier et en extraire les coordonnées GPS qui s'y trouvent. Car, après tout, ce que tu veux obtenir, c'est "simplement" une chaine de caractères (qui pourra être représentée sous la forme d'une std::string) et deux double (le type primitif double que le compilateur connait sans même avoir besoin d'inclure le moindre fichier d'en-tête).

    Mieux encore, tu n'as absolument aucun besoin de créer une classe, dont les données qui la composent seraient dans l'accessibilité privée et qui exposerait quelques services "qui vont bien": Tu peux créer ce que l'on appelle un POD (pour Plain Old Data), ou, si tu préfères, une bonne vieille structure telle que l'on en créait déjà en C.

    Ainsi, tu pourrais tout à fait créer une structure proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct GpsCoordinate{
        std::string code;
        double longitude;
        double latitude;
    };
    Et comme tu voudras manipuler plusieurs coordonnées GPS, il serait sans doute utile de créer la notion de "conteneur de coordonnées GPS".

    Cette notion peut être une classe, car, on se rend compte que l'on attendra de sa part "un certain nombre" de services, mais que celui qui va l'utiliser se fout royalement de "comment elle s'y prend" pour les rendre.

    Bien sur, nous pourrions décider de représenter cette notions par un "simple" alias de type(comme using GpsCoordinateHolder = std::vector<GpsCoordinate>;, mais la classe std::vector expose énormément de services, et il n'y en a qu'une toute petite partie qui nous intéresse. Or, le principe de création des différentes notions que l'on développe est de
    faire en sorte que notre classe soit facile à utiliser correctement et difficile à utiliser de manière incorrecte.
    L'utilisation d'un alias de type rendra très facile le fait d'utiliser notre notion de manière incorrecte. Il est donc préférable de fournir une classe qui n'exposera que les services dont on a vraiment besoin, et ce, même si elle utilise la classe std::vector en interne (mais ca, celui qui va utiliser la classe en question s'en fout royalement!). Elle pourrait prendre une forme proche 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
    class GpsCoordinateHolder{
    public:
        /* on veut sans doute pouvoir connaitre le nombre de coordonnées GPS dont on dispose */
        size_t size() const{
            return datas_.size();
        }
        /* on veut pouvoir accéder EN LECTURE SEULE à une coordonnée GPS particulière */
        GpsCoordinate const & operator[](size_t index) const; // je passe l'implémentation ;)
        /* on veut pouvoir parcourir EN LECTURE SEULE l'ensemble des coordonnées GPS à l'aide d'itérateurs */
        using const_iterator =  typename std::vector<GpsCoordinate>::const_iterator;
        const_iterator begin() const{
            return datas_.begin();
        }
        const_iterator end() const{
            return datas_.end();
        }
        /* on veut pouvoir supprimer TOUTES les coordonnées GPS */
        void clear(){
            datas_.clear();
        }
        /* et on veut pouvoir charger un ensemble de coordonnées GPS
         * depuis un fichier quelconque (dont le nom nous est donné
         */
        void loadFromFile(std::string const & filename); // je passe l'implémentation ;)
                                                       // utilise std::ifstream en interne :D
    private:
        std::vector<GpsCoordinate> datas_;
    };
    Avec cette structure (GpsCoordinate) et cette classe (GpsCoordinateHolder) nous avons les moyens de représenter toutes les données métier que tu as parlé jusqu'à présent. Et il n'en faut pas plus ! Tu n'as aucun besoin de passer par le framework Qt pour représenter tes données métier

    Enfin, il n'en faut pas plus... en l'état de ce que je sais de ton projet Car nous pourrions envisager de créer une structure permettant de convertir les double que nous avons obtenus en degrés de longitude et de latitude, qui pourrait aussi bien prendre une forme proche 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
    struct Degree{
        enum Type{
            longitude,
            latitude
        }; 
        enum Direction{
            north,
            south,
            east,
            west
        };
        Degree(double value, Type t):type{t}{/* ... */}
        Type type;
        Direction direction;
        unsigned short degree;
        unsigned short minutes;
        unsigned short seconds;
        unsigned double decimalPart;
    };
    Mais bon, ce sera à toi de voir si tu as besoin de cela au niveau de tes données métier, ou si tu peux te contenter des GpsCoordinate

    Par contre, ce n'est qu'une fois que tu auras ces données métier que tu pourra commencer à t'inquiéter des différentes représentations qui en sont faites (dans ton interface graphique, par exemple).

    L'idée sera alors de créer une (ou sans doute plusieurs) vues dans Qt, qui correspondra (correspondront chacune) à une manière de représenter tes données que tu souhaite proposer à l'utilisateur de ton application et un (ou sans doute plusieurs) "modèle(s) de conversion" (attention, cela n'a rien à voir avec la notion de modèle que l'on retrouve dans MVC, même si le terme est semblable ) qui permetra (qui permettront) de "remplir" cette (ces) vue(s) avec tes données métier.

    Enfin, si tu souhaites modifier les données métier (c'est souvent le cas, quand on propose une IHM), tu créera un (ou sans doute plusieurs) "contrôleur(s)" (ou plutôt "délégué(s)") qui s'occupera (qui s'occuperont) de traiter tous les événement susceptibles de provoquer une modification des données générés par la (les) vue(s) et de faire appel aux fonctions exposée par ta partie métier.

    En travaillant de la sorte, ta partie métier va rester totalement "agnostique": si, un jour, tu décide de créer une autre application en utilisant un autre framework, tu n'auras qu'à prendre toutes les classes (et structures) "métier", et "tout ce qu'il te restera à faire", c'est de créer tes vues et tes contrôleurs / délégués en utilisant cet autre framework.
    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

  2. #22
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Points : 103
    Points
    103
    Par défaut
    Que dire devant une telle explication ? Et bien tout simplement, merci.

    De fait, tu confortes et enrichis la remise de mon ouvrage sur le métier. J'ai justement pris pour direction cette voie de passer à une structure MVD pour mon application et j'ai entièrement repris mon code en ce sens. Ca marche relativement bien, ce nouveau départ est meilleur.

    Je vais donc maintenant comparer le code que j'ai déjà sur ma partie métier avec celui que tu me proposes, et l'améliorer de nouveau.

    Toujours un plaisir de poster sur ce forum.

    Merci encore.

  3. #23
    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
    Citation Envoyé par KonTiKI Voir le message
    Je vais donc maintenant comparer le code que j'ai déjà sur ma partie métier avec celui que tu me proposes, et l'améliorer de nouveau.
    Oui, mais... heu...

    Fais gaffe quand même! ("marche à l'ombre", comme disait l'autre
    )...

    N'oublie quand même pas que je n'ai fourni mes explications -- et surtout le code -- que sur base d'une connaissance très fragmentaire de ton projet et de tes besoins.

    S'il n'y a (et encore ! ) rien à redire en ce qui concerne MVC/MVD, pour tout ce qui a trait au code, il se peut que je sois parti sur des hypothèses totalement foireuses!

    Tu dois donc bien prendre conscience que le code n'est jamais qu'un exemple de ce qui pourrait se faire, même si les explications que j'ai pu donner à son sujet semblent "raisonnables" de manière générale

    Tu peux donc t'inspirer de mon code -- c'est l'objectif -- mais tu ne dois pas perdre de vue les besoins et les objectifs de ton projet pour autant, hein?
    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

Discussions similaires

  1. Réponses: 3
    Dernier message: 24/03/2011, 15h58
  2. accéder à variable privée d'une classe à partir d'une autre classe
    Par restapa dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 05/08/2010, 08h56
  3. modifier une variable d'une classe à partir d'une autre classe
    Par Rniamo dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 16/03/2008, 20h40
  4. Réponses: 2
    Dernier message: 29/03/2007, 14h08
  5. Accéder à des objets d'une Form à partir d'une classe
    Par kinouseb dans le forum Windows Forms
    Réponses: 4
    Dernier message: 23/01/2007, 18h07

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