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 :

Petit problème d'héritage [Débutant(e)]


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 4
    Par défaut Petit problème d'héritage
    Bonjour les amis,

    J'ai besoin de comprendre une petite chose concernant les listes et l'héritage.

    En effet, c'est un petit problème que j'ai rencontré en utilisant Qt, mais je pense que c'est un problème C++ plutôt, d'où mon poste ici.

    J'ai simplifier mon problème au maximum, j'ai une QMainwindow qui contient deux listes d'object héritant tout les deux d'une classe GraphicsView qui hérite à son tour de la class QGraphicsView. Le .h de la mainwindow est donc le suivant:
    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
     
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
     
    #include <QMainWindow>
    #include "graphicsview.h"
    #include "specialview1.h"
    #include "specialview2.h"
     
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
     
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
     
        QList<GraphicsView*> getGraphics();
     
    private:
        QList<SpecialView1*> _graphicsS1;
        QList<SpecialView2*> _graphicsS2;
     
        bool test;
    };
     
    #endif // MAINWINDOW_H
    dans le .cpp j'ai une methode getter qui doit renvoyer une des deux liste en fonction du boolean test:
    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
     
    #include "mainwindow.h"
    #include "graphicsview.h"
     
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent)
    {
        test = true;
    }
     
    MainWindow::~MainWindow()
    {
    }
     
    QList<GraphicsView*> MainWindow::getGraphics()
    {
        if( test )
            return _graphicsS1;
        else
            return _graphicsS2;
    }
    J'arrive enfin à mon problème, la compilation de ce code me donne l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    D:\Qt\QtCreator2.4.1\Autres\mainwindow.cpp:21: erreur : conversion from 'QList<SpecialView1*>' to non-scalar type 'QList<GraphicsView*>' requested
    et...
    D:\Qt\QtCreator2.4.1\Autres\mainwindow.cpp:24: erreur : conversion from 'QList<SpecialView2*>' to non-scalar type 'QList<GraphicsView*>' requested
    j'aimerais comprend pourquoi cette erreur, pour je suis obliger de faire la conversion à la main!?

    Merci d'avance pour votre aide

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Bonjour ohichamo

    QList<SpecialView1*> et QList<SpecialView2*> sont des types indépendants qui n'ont pas de lien avec QList<SpecialView*>. Bien que ces classes utilisent le même template, le type C++ obtenu est unique et aucune méthode de conversion automatique n'existe. Si la conversion de SpecialView1* vers SpecialView* est bien correcte et naturelle, rien ne permet de le généraliser à tout template qui les utilisent.

    Si tu voulais profiter de l'héritage pour une correction, il aurait fallu que:
    - QList<SpecialView1*> et QList<SpecialView2*> héritent de QList<SpecialView*>
    - Tu utilises des pointeurs vers les listes et pas les listes directement.

    Attention, ce n'est pas la solution ! Une solution rapide est d'écrire le code qui remplit une QList<SpecialView*> avec le contenu de la liste appropriée dans la méthode getGraphics(), mais ça fait un parcours de boucle coûteux et pas vraiment productif.

    Une meilleure solution, c'est de ne stocker que des QList<SpecialView*> et de ne manipuler que des SpecialView*, quand bien même les objets instanciés sont bien de la classe SpecialView1 et SpecialView2. Il n'y a pas de raison à priori que SpecialView1 et SpecialView2 fournissent des services différents et qui s'appellent différemment, selon le principe de Liskov. Si c'est le cas, c'est qu'il doit y avoir un problème de conception des classes, que nous pourrons peut être t'aider à résoudre.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 4
    Par défaut
    Merci beaucoup jblecanard pour ta réponse rapide et précise.

    Je commence "grâce à toi" à comprendre un peu le problème. Corrige moi si je me trompe! "QList<mâle*>" est considéré comme un objet a part entier et donc le compilateur trouve que QList<Femelle*> est un objet complétement différent, même si "mâle" et "femelle" hérite tous les deux de "Humain".

    d'autre part, tu as réussi à me mettre le doute pour la conception :-/
    En fait, j'essaye de coder deux type de vue (héritant de QGraphicsView), l’exemple type des différences entre les deux vues, est l’édition par exemple, une des deux vue, doit permettre l’édition des item et l'autre seulement l'affichage.

    Le problème est simplifier au maximum, je ne peux pas coder directement cette distinction entre type d'utilisation des vues dans la même class, car cela me surchargera encore plus le code (j'ai aussi à distinguer les vue par rapport à un type, vues chambre, vues étage et vue maison ).
    J'avais un autre choix, qui est de créer trois type de vues et gérer le niveau d'utilisateur (admin ou non) directement dedans, mais je ne pourrais toujours pas respecter le principe de Liskov :s (que je ne connaissais pas)

    Si tu vois une meilleur conception (toi ou une autre âme charitable), je suis preneur

    Merci encore

  4. #4
    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,

    Quand tu regardes la manière dont Qt organise ses objets de type QGraphicsXXX, on constate qu'il y a trois gros niveau:

    1 - QGraphicsItem, qui correpond à chaque partie plus ou moins atomique pouvant être dessinée (lignes, texte, formes géométriques, ...)

    2 - QGraphicsScene, qui contient un ensemble de QGraphicsItem devant être affichés ensembles.

    Il s'agit de la surface sur laquelle vont s'afficher tous les QGraphicsItem intervenant dans un dessin

    3 - QGraphicsView qui est le widget (comprend : l'élément de l'IHM, pour ainsi dire au même titre qu'un bouton ou qu'une zone d'édition de texte) qui va contenir la scene pour l'intégrer dans l'IHM de ton application.

    Il ne me semble pas opportun de faire la distinction, en termes de classe du moins, entre une vue "Read only" et une vue "modifiable".

    La raison est bien simple : le fait que la vue soit modifiable (ou non) peut etre considérée comme une propriété basique de la vue, qui peut en interne etre représentée par un simple booléen qu'il suffit de tester, dans les fonctions qui vont essayer de modifier scene, avant de donner le "go / no go" à la transmission des instructions à la scene

    De plus, je présume que tu vas prévoir un certain nombre (pour ne pas dire un nombre certain ) d'actions potentielles, dont certaines seront actives en mode "read only" (et donc aussi en mode "modifiable") et dont les autres ne seront actives que pour le mode "édition".

    Il peut sembler logique que ces actions, connectées à la vue, s'en réfèrent à la vue pour déterminer leur état d'activation, et l'existence de deux types de vues ne différant que par leur statut "d'éditabilité" ne t'apporterait finalement pas grand chose

    La scene, quant à elle, pourrait être considérée par défaut comme étant éditable, étant donné qu'elle est "bien au chaud, planquée derrière la vue" et que la vue sert, finalement, de "pare feu" qui évitera toute tentative de modification indue.

    S'il doit y avoir une distinction entre différents aperçus, je me dis que ce devrait être au niveau de la scene, de manière à accepter (ou non) les éléments qui sont susceptibles d'intervenir dans l'ensemble en fonction de leur type (du gason pouvant par exemple apparaitre dans une scene extérieure, mais étant plus difficile à caser dans une scene représentant une chambre .

    Cependant, je ne suis pas d'avantage persuadé de l'intérêt de créer différents types de scène permettant de représenter l'une une scene extérieure, l'autre une scene de chambre ou la troisième une vue de cuisine...

    Car, à bien y réfléchir, une scene n'est jamais qu'une collection d'objets qui n'a donc, a priori, pas à s'inquiéter outre mesure des objets qu'on lui transmet.

    La décision d'ajouter ou non un type d'objet particulier dans une scène particulière devrait intervenir au niveau du contrôleur qui s'occupe de remplir la scene et pourrait assez facilement y arriver en ayant, simplement, une valeur énumérée sur laquelle se baser afin de déterminer si un objet particulier a réellement sa place dans une scène particulière

    Je verrais donc bien une classe que nous pourrions nommer "SceneEditor" qui serait dérivée en OutdoorSceneEditor, IndorSceneEditor, KitchenSceneEditor, RoomSceneEditor et autres qui eux se chargeraient de décider si tel type d'objet (un lit, par exemple) a réellement sa place dans une scène particulière.

    Cette classe pourrait se trouver à mi chemin entre un pattern mediateur, dans le sens où elle ferait le lien entre une scène et les objets qu'elle contient et le visiteur, dans le sens où elle pourrait décider d'insérer ou non un objet, en fonction du type d'objet à insérer.

    Cette hiérarchie de classes serait avantageusement complétée par une fabrique d'éditeur de scene se basant sur une valeur énumérée représentant le type de scène sur lequel on travaille pour renvoyer... l'éditeur "qui va bien"

    Le raisonnement que j'ai suivi se base essentiellement sur le fait qu'il existe un autre grand principe de programmation qui conseille de garder une responsabilité unique à tout ce que l'on peut créer.

    Etant donné que la vue, la scène et même les différents objets qui composent une scène ont déjà une responsabilité clairement définie, il semble logique de faire en sorte que la responsabilité d'accepter ou non de placer un type particuiler d'objet dans une scène particulière soit... déléguée à quelque chose qui ne fait que ca

    Du coup, tu n'aurais plus vraiement de problème : tu pourrais manipuler deux QList<GraphicsView *> et décider de renvoyer l'une ou l'autre en fonction des conditions spécifiées

    Tu pourrais d'ailleurs tout aussi bien décider (si le besoin s'en fait sentir du moins) de mélanger des vues modifiable et des vues non modifiables (après tout, ce type d'information tient sur un booléen ) sans que cela ne pose de problème
    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. Petit Problème d'héritage?
    Par Enjaye dans le forum C++
    Réponses: 9
    Dernier message: 14/11/2012, 14h48
  2. Petit problème d'héritage.
    Par tifil dans le forum C++
    Réponses: 19
    Dernier message: 08/03/2012, 18h04
  3. Petit problème d'héritage
    Par AF_2.8 dans le forum C++
    Réponses: 4
    Dernier message: 02/12/2010, 16h33
  4. Héritage : petit problème
    Par Fy_Hertz dans le forum C++
    Réponses: 20
    Dernier message: 31/01/2006, 08h39
  5. [jointure] Petit problème sur le type de jointure...
    Par SteelBox dans le forum Langage SQL
    Réponses: 13
    Dernier message: 13/02/2004, 18h55

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