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 :

Précisions sur le mot clé virtual protected


Sujet :

C++

  1. #1
    Invité
    Invité(e)
    Par défaut Précisions sur le mot clé virtual protected
    Bonjour,

    J'aimerais quelques précisions sur comment fonctionne le mot clé virtual protected.
    En fait j'ai l'impression de confondre membre d'une classe et objet instancié par la classe.
    A travers mon exemple j'essaierai de vous expliquer ce que j'ai compris intuitivement.
    Alors voilà : d'abord il y a ma classe MainWindow :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
     
    public:
        explicit MainWindow(QWidget *parent = 0);    
        ~MainWindow();
     
    private:
        Phonon::VideoWidget vw;
    };
    Ici je l'intéresserai à la fonction mousedoubleclick() qui est virtual protected (peu importe les paramètres ici).

    Un peu plus loin dans le code je fais ceci à l'intérieur d'une fonction membre privée de ma classe MainWindow :Et là le compilateur bloque et dit que la fonction mousedoubleclick() est protected.

    Voilà maintenant ce que j'ai compris (mais je ne suis vraiment pas sûr du tout) :

    => un objet instancié de type Phonon::VideoWidget n'est pas membre de cette classe ? Il contiendra les membres (fonctions, variable) mais n'en n'est pas un ?

    => vw est de type VideoWidget et membre privé de MainWindow : est-ce parce que vw est privé que le compilo bloque ?

    => virtual protected signifie que la fonction est utilisable par les membres de la classe mais peut l'être aussi par les membres des classes dérivées ?

    Je ne suis pas sûr du tout de ça. Si vous pouvez m'éclairer sur ces 3 points je vous remercie je sens que c'est un concept très important.

    En fait dans le code voilà ce que j'ai compris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Phonon::VideoWidget vw; // dans la classe MainWindow je crée un objet de type VideoWidget (cet objet est membre de la classe MainWindow)
    (...)
    vw.mousedoubleclick(); // à l'intérieur d'un membre de MainWindow j'appelle une fonction virtual protected appartenant à une classe extérieure à MainWindow
    Bonne journée. Cordialement, Gizmo.

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2010
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Tout d'abords le sens des mots clefs 'virtual' et 'protected' n'est pas lié (Cf la FAQ C++ pour les détails).
    Ici, c'est 'protected' qui est intéressant:
    Cela signifie que ta méthode ne peut être appelée que par un objet de la classe (ici, Phonon::VideoWidget) ou un objet dont la classe hérite de Phonon::VideoWidget. En aucun cas cette méthode mousedoubleclick() ne peut être appelée depuis un objet de classe MainWindow, même si l'objet Phonon::VideoWidget est membre de MainWindow.
    'Être membre' ne signifie pas 'hériter de'!

  3. #3
    Invité
    Invité(e)
    Par défaut
    D'accord merci à toi.
    Donc même si je mets mon objet vw en public cela n'y changera rien-du-tout ?

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2010
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Mettre vw en public aura pour effet de rendre le vw accessible aux objets qui utiliseraient ta classe MainWindow. On alors pourrai faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MainWindow win;
    win.vw.methodeDeVideoWidget();
    ...ce qui n'est pas ce que tu veux ici.
    Ici, la methode Phonon::VideoWidget::mousedoubleclick() est déclarée protected, donc pour l'utiliser depuis l'extérieur de VideoWidget, il faut que t en "donne l'accès".
    Pour cela il te faut définir ta propre classe de VideoWidget (par exemple MyVideoWidget), qui hérite de VideoWidget : cette classe aura accès à la méthode mouseDoubleClick de VideoWidget. Il suffit alors d'encapsuler l'appel à VideoWidget::mouseDoubleClick () dans une méthode publique de MyVideoWidget:
    Par exemple tu pourrais faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class MyVideoWidget : public Phonon::VideoWidget
    {
     public:
       void mouseDoubleclick();
    }
     
    MyVideoWidget::mouseDoubleclick()
    {
    //....
     VideoWidget::mouseDoubleclick();
    //....
    }

  5. #5
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Je suppose que tu parles de la foncton mouseDoubleClickEvent ?

    C'est normal qu'elle soit en protected... car le but est de ne pas pouvoir l'appeler directement.

    Le but des fonctions xxxEvent est de faciliter la gestion des events pour l'utilisateur final. Il suffit de redéfinir dans ces fonctions le comportement que l'on souhaite implémenter, le reste (capture d'un évènement généré par l'utilisateur ou autre, création du QEvent correspondant, traitement des events, dispatching des events, etc.) est réalisé automatiquement pas Qt.

    Donc si tu veux simuler un double clic, il ne faut pas appeler cette fonction, il faut créer un QMouseEvent de type QEvent::MouseButtonDblClick et l'envoyer à la boucle d'event avec QCoreApplication::postEvent.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Ok alors j'avais à peu près tout compris alors... Ou presque...

    Par contre pour le QMouseEvent j'avais deviné mais pas pour QCoreApplication... D'ailleurs si vous ne l'aviez pas dit je n'aurai jamais deviné.

    Ca a l'air assez difficile à faire cependant mais on doit "jubiler" quand on sait le faire.

    Aussi j'avais l'intention de créer mon propre signal avec la classe QSignalMapper (je ne sais pas trop j'ai vu ça je ne sais plus trop où...), mais à l'heure qu'il est je ne sais pas encore vers quelle solution me tourne, tout débutant newbie des prairies que je suis...

    PS : j'aimerais être sûr pour l'encapsulation : sur la FAQ il est dit que, je cite
    Un membre déclaré public dans une classe peut être accédé par toutes les autres classes et fonctions.
    Donc pour mon exemple, si vw de classe VideoWidget est public dans MainWindow alors le code suivant marche non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this->vw.mouseDoubleClickEvent();
    Dernière modification par Invité ; 19/07/2011 à 17h59.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2010
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Non, tu ne pourras pas appeler une methode private/protected de VideoWidget, donc ton appel ne compileras pas.
    Dans le cas que tu présente, tu pourras faire appel à des methodes publiques de VideoWidget:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this->vw.uneMethodePubliqueDeVW()
    De plus, si tu n'utilise ton VideoWidget que dans MainWindow (et que le VW est membre de MainWindow), il n'y a aucune raison de le rendre publique, tu peux faire l'appel suivant dans toute methode de MainWindow:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vw.uneMethodePubliqueDeVW();

  8. #8
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Hum... attention gizmo27, tu vas te faire gronder par John s'il apprend que le travail qui est fait pour traduire les pages de la doc de Qt en français n'est pas lu Le système d'événements

    Pour la création d'un event, c'est en fait très simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    qApp->postEvent(ton_widget, new QMouseEvent(QEvent::MouseButtonDblClick, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
    (je te laisse regarder la doc de QMouseEvent pour comprendre les paramètres)

    Pour les signaux, tu n'as pas besoin (à priori) de passer par QSignalMapper. On peut créer un signal dans n'importe quelle classe dérivant de QObject (donc en particulier QMainWindow) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class MainWindow : public QMainWindow
    {
       ...
    signals:
       void un_nouveau_signal();
    };
     
    // pour émettre un signal
    emit un_niveau_signal();
    (QSignalMapper sert à autre chose : a recevoir des signaux provenant de sources multiples dynamiques)


    Pour le problème de public/protected, tu sembles oublier que vm est effectivement public donc accessible en dehors de la classe MainWindow. Par contre, mouseDoubleClickEvent est protected et donc inaccessible en dehors de la classe VideoWidget et dérivées.

    C'est 2 problèmes différents donc focalise toi en premier sur le problème des private/public/protected (c'est fondamentale en C++). Tu pourras passer au problèmes des events Qt dans un second temps.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Merci pour la réponse je vais en effet me concentrer sur le trio PPP avant tout ça me semble important en effet, fondamental comme vous dites.

    Et pour ce qui est de la doc je l'ai lu plusieurs fois déjà. Mais j'ai un peu de mal ne m'en voulez pas : jusqu'à maintenant je me cantonnais aux signaux déjà existants et je faisais QObject::connect() ce qui me suffisait.

    A mon avis la compréhension fonctionnement du gestionnaire d'évènements n'est pas si facile poir un "low-level developper" comme moi : où les variables vont et comment elles arrivent : comment le programme "capte" le double-clic...

    Cordialement, Gizmo.

  10. #10
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Bon ça chambre et tout et tout mais personne ne m'a dit si mes 3 "début d'intuition" (avec les flèches "=>", voir 1er post) étaient bonnes...
    Rhalala c'est pas sérieux mdr

    En vous remerciant d'avance. bonne journée à vous. Cordialement, Gizmo.

    EDIT : hum... zut je viens de voir à la FAQ Qt un truc sur les évènements... là j'ai aucune excuses... Bien joué gbdivers vous l'emportez haut-la-main 2 jeux à 1.
    Jeu Set et Match
    Dernière modification par Invité ; 20/07/2011 à 17h07.

  11. #11
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    personne ne m'a dit si mes 3 "début d'intuition"
    En fait, il me semble que les réponses de Peeter répondaient à ces questions. Tu devrais les relire
    Pour reprendre chaque point :
    => un objet instancié de type Phonon::VideoWidget n'est pas membre de cette classe ? Il contiendra les membres (fonctions, variable) mais n'en n'est pas un ?
    La classe MainWindow contient une variable membre de type Phonon::VideoWidget donc lors de l'instanciation ( = lors de la création de l'objet en mémoire et appelle du constructeur) de la classe MainWindow, un objet VideoWidget sera instancié aussi.

    => vw est de type VideoWidget et membre privé de MainWindow : est-ce parce que vw est privé que le compilo bloque ?
    Non. vm est privé = il n'est accessible que dans la classe. Donc si tu l’appelles dans une fonction membre de MainWindow, ça ne pose pas de problème.
    Par contre, mousedoubleclick est protected dans VideoWidget donc cette fonction ne peut être appelée que dans la classe VideoWidget ou une classe dérivée.

    => virtual protected signifie que la fonction est utilisable par les membres de la classe mais peut l'être aussi par les membres des classes dérivées ?
    Oui.


    Ce sont des questions de vocabulaire de base en C++ et les liens donnés vers la FAQ répondaient déjà à ces questions

  12. #12
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Merci à vous.
    En fait ce que je n'avais pas compris c'est : j'appelle la fonction depuis où ? Ici c'est depuis la classe MainWindow.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this->vw.mousedoubleclick();
    En gros ici j'appelle mousedoubleclick() MAIS depuis un membre de MainWindow, alors que je n'ai le droit de l'appeler que depuis un membre de la classe VideoWidget...
    C'est pour ça que le programme bloque.

    Cordialement, Gizmo.

    PS : en fait ici j'ai tout simplement omis de faire attention à "tel objet est membre de telle classe" et "telle fonction est appelée depuis telle classe" : et je suis tombé dedans...

  13. #13
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Oui, d'où la solution de Peeter t'a proposé dans le 4ème message : créer une classe MyVideoWidget héritant de VideoWidget qui propose une fonction public dans laquelle on appelle la fonction mouseDoubleclick. Dans ce cas, depuis MainWindow, la fonction MyVideoWidget::mouseDoubleclick est public, donc pas de problème, et dans cette fonction, VideoWidget::mouseDoubleclick est protected donc accessible aussi puisque c'est une classe dérivée. Avec cette solution, il n'y a plus de problème d'accès.

    Mais il reste le problème qu'il ne faut pas normalement appeler une fonction de traitement des events de Qt directement mais c'est un autre problème. Si tu as compris le principe des private, protected et public, c'est bien.

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

Discussions similaires

  1. demande de précision sur le mot-clef volatile
    Par archimondain dans le forum Threads & Processus
    Réponses: 13
    Dernier message: 01/03/2012, 19h27
  2. Précision sur Oracle 9iAS r2
    Par Patmane dans le forum Oracle
    Réponses: 9
    Dernier message: 18/03/2007, 04h41
  3. Précisions sur Import/export
    Par electro dans le forum Import/Export
    Réponses: 9
    Dernier message: 15/10/2004, 13h34
  4. [Observateur] Précisions sur le design pattern Observer [UML]
    Par joquetino dans le forum Design Patterns
    Réponses: 2
    Dernier message: 07/10/2004, 22h35
  5. Précision sur les sauvegarde à chaud
    Par alxkid dans le forum Administration
    Réponses: 2
    Dernier message: 09/08/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