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 :

problem d'implementation d'une methode virtual


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Tunisie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 141
    Points : 59
    Points
    59
    Par défaut problem d'implementation d'une methode virtual
    Bonjour ,

    j'ai une question concernant les methodes "virtelles",si j'ai bien compris,ces methodes là on peut les modifier dans les classe filles.
    ma question est :
    j'ai un fichier : ExaminerViewer.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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    oQtExaminerViewer::SoQtExaminerViewer(QWidget * parent,
                                           const char * name,
                                           SbBool embed,
                                           SoQtFullViewer::BuildFlag flag,
                                           SoQtViewer::Type type)
      : inherited(parent, name, embed, flag, type, FALSE)
    {
      PRIVATE(this) = new SoQtExaminerViewerP(this);
      PRIVATE(this)->constructor(TRUE);
    }
     
    // *************************************************************************
     
    // Documented in common/viewers/SoGuiExaminerViewer.cpp.in.
    SoQtExaminerViewer::SoQtExaminerViewer(QWidget * parent,
                                           const char * name,
                                           SbBool embed,
                                           SoQtFullViewer::BuildFlag flag,
                                           SoQtViewer::Type type,
                                           SbBool build)
      : inherited(parent, name, embed, flag, type, FALSE)
    {
      PRIVATE(this) = new SoQtExaminerViewerP(this);
      PRIVATE(this)->constructor(build);
    }
     
    // *************************************************************************
     
    SoQtExaminerViewer::~SoQtExaminerViewer()
    {
      delete PRIVATE(this);
    }
     
    // *************************************************************************
     
    // Documented in superclass.
    void
    SoQtExaminerViewer::setCamera(SoCamera * newCamera)
    {
      // This method overridden from parent class to toggle the camera
      // type selection button pixmap and string of the zoom/dolly
      // thumbwheel.
     
      if (newCamera) {
        SoType camtype = newCamera->getTypeId();
        SbBool orthotype =
          camtype.isDerivedFrom(SoOrthographicCamera::getClassTypeId());
     
        this->setRightWheelString(orthotype ? "Zoom" : "Dolly");
        if (PRIVATE(this)->cameratogglebutton) {
          PRIVATE(this)->cameratogglebutton->setPixmap(orthotype ?
                                                       * (PRIVATE(this)->orthopixmap) :
                                                       * (PRIVATE(this)->perspectivepixmap));
        }
      }
     
      inherited::setCamera(newCamera);
    }
     
    // *************************************************************************
     
    // Documented in superclass. Overridden so we can append the camera
    // type switch button in the rightside button column.
    void
    SoQtExaminerViewer::createViewerButtons(QWidget * parent, SbPList * buttonlist)
    {
      inherited::createViewerButtons(parent, buttonlist);
     
      PRIVATE(this)->cameratogglebutton = new QPushButton(parent);
     
    #if (defined Q_WS_MAC && QT_VERSION >=0x030100) && defined(HAVE_QSTYLEFACTORY_H)
        // Since Qt/Mac 3.1.x, all pushbuttons (even those < 32x32) are drawn
        // using the Aqua style, i.e. with rounded edges and shading. This
        // looks really ugly in the viewer decoration. Drawing the buttons
        // in the Windows style gives us the flat, square buttons we want.
      QStyle * style = QStyleFactory::create("windows");
      if (style) { PRIVATE(this)->cameratogglebutton->setStyle(style); }
    #endif
     
      PRIVATE(this)->cameratogglebutton->setFocusPolicy(QTWIDGET_NOFOCUS);
      assert(PRIVATE(this)->perspectivepixmap);
      assert(PRIVATE(this)->orthopixmap);
     
      QPixmap * p = NULL;
      SoType t = this->getCameraType();
      if (t.isDerivedFrom(SoOrthographicCamera::getClassTypeId()))
        p = PRIVATE(this)->orthopixmap;
      else if (t.isDerivedFrom(SoPerspectiveCamera::getClassTypeId()))
        p = PRIVATE(this)->perspectivepixmap;
      else assert(0 && "unsupported cameratype");
     
      PRIVATE(this)->cameratogglebutton->setPixmap(*p);
      PRIVATE(this)->cameratogglebutton->adjustSize();
     
      QObject::connect(PRIVATE(this)->cameratogglebutton, SIGNAL(clicked()),
                       PRIVATE(this), SLOT(cameratoggleClicked()));
     
      buttonlist->append(PRIVATE(this)->cameratogglebutton);
    }
     
    // *************************************************************************
     
    // SoQtExaminerViewerP "private implementation" class.
     
    #ifndef DOXYGEN_SKIP_THIS
     
    SoQtExaminerViewerP::SoQtExaminerViewerP(SoQtExaminerViewer * publ)
      : SoGuiExaminerViewerP(publ)
    {
    }
     
    SoQtExaminerViewerP::~SoQtExaminerViewerP()
    {
      // Button pixmaps.
      delete this->orthopixmap;
      delete this->perspectivepixmap;
     
      this->genericDestructor();
    }
     
    // This contains the real constructor code (the two SoQtExaminerViewer
    // constructors are only entry points for this method).
    void
    SoQtExaminerViewerP::constructor(SbBool build)
    {
      this->genericConstructor();
     
      this->cameratogglebutton = NULL;
     
      this->orthopixmap = new QPixmap((const char **)ortho_xpm);
      this->perspectivepixmap = new QPixmap((const char **)perspective_xpm);
      assert(this->orthopixmap->size() == this->perspectivepixmap->size());
     
      PUBLIC(this)->setClassName("SoQtExaminerViewer");
     
      PUBLIC(this)->setPopupMenuString("Examiner Viewer");
      PUBLIC(this)->setLeftWheelString("Rotx");
      PUBLIC(this)->setBottomWheelString("Roty");
     
      if (build) {
        QWidget * widget = PUBLIC(this)->buildWidget(PUBLIC(this)->getParentWidget());
        PUBLIC(this)->setBaseWidget(widget);
      }
    }
     
    void
    SoQtExaminerViewerP::cameratoggleClicked()
    {
      if (PUBLIC(this)->getCamera()) PUBLIC(this)->toggleCameraType();
    }
     
    // *************************************************************************
     
    #endif // DOXYGEN_SKIP_THIS
     
    #undef PRIVATE
    #undef PUBLIC
    un ExaminerViewerP.h qui est finalement le header du ExaminerViewer.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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class SoQtExaminerViewer;
    class QPixmap;
     
    // ************************************************************************
     
    // This class contains private data and methods used within the
    // SoQtExaminerViewer class.
     
    class SoQtExaminerViewerP : public QObject, public SoGuiExaminerViewerP
    {
      Q_OBJECT
     
    public:
      SoQtExaminerViewerP(SoQtExaminerViewer * publ);
      ~SoQtExaminerViewerP();
     
      void constructor(SbBool buildNow);
     
      QPixmap * orthopixmap, * perspectivepixmap;
      class QPushButton * cameratogglebutton;
     
    public slots:
      // viewer buttons row:
      void cameratoggleClicked(void);
    };
     
    // ************************************************************************
     
    #endif // ! SOQTEXAMINERVIEWERP_H
    et un SoQtExaminerviewer.h
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    #ifndef SOQT_EXAMINERVIEWER_H
    #define SOQT_EXAMINERVIEWER_H
     
    #include <Inventor/SbLinear.h>
    #include <Inventor/Qt/viewers/SoQtFullViewer.h>
     
    class SoSeparator;
    class SoSwitch;
    class SoTranslation;
    class SoScale;
     
    class SoQtThumbWheel;
     
    // *************************************************************************
     
    class SOQT_DLL_API SoQtExaminerViewer : public SoQtFullViewer {
      SOQT_OBJECT_HEADER(SoQtExaminerViewer, SoQtFullViewer);
     
    public:
      SoQtExaminerViewer(QWidget * parent = NULL,
                            const char * name = NULL,
                            SbBool embed = TRUE,
                            SoQtFullViewer::BuildFlag flag = BUILD_ALL,
                            SoQtViewer::Type type = BROWSER);
      ~SoQtExaminerViewer();
     
      void setAnimationEnabled(const SbBool enable);
      SbBool isAnimationEnabled(void) const;
     
      void stopAnimating(void);
      SbBool isAnimating(void) const;
     
      void setFeedbackVisibility(const SbBool enable);
      SbBool isFeedbackVisible(void) const;
     
      void setFeedbackSize(const int size);
      int getFeedbackSize(void) const;
     
      virtual void setViewing(SbBool enable);
      virtual void setCamera(SoCamera * camera);
      virtual void setCursorEnabled(SbBool enable);
     
    protected:
      SoQtExaminerViewer(QWidget * parent,
                            const char * name,
                            SbBool embed,
                            SoQtFullViewer::BuildFlag flag,
                            SoQtViewer::Type type,
                            SbBool build);
     
      virtual void leftWheelMotion(float val);
      virtual void bottomWheelMotion(float val);
      virtual void rightWheelMotion(float val);
     
      virtual void createViewerButtons(QWidget * parent, SbPList * buttonlist);
     
      virtual const char * getDefaultWidgetName(void) const;
      virtual const char * getDefaultTitle(void) const;
      virtual const char * getDefaultIconTitle(void) const;
     
      virtual SbBool processSoEvent(const SoEvent * const event);
      virtual void setSeekMode(SbBool enable);
      virtual void actualRedraw(void);
     
      virtual void afterRealizeHook(void);
     
    private:
      class SoQtExaminerViewerP * pimpl;
     
      friend class SoGuiExaminerViewerP;
      friend class SoQtExaminerViewerP;
    };
     
    #endif // ! SOQT_EXAMINERVIEWER_H
    dans le SoQtExaminerViewer.h on declare SoQtExaminerViewerP comme classe amie.
    et au final,dans mon code,je fais un include de <SoQtExaminerViewer.h>

    je dois ajouter un bouton à mon viewer et donc je remarque que je peux utiliser createViewerButtons qui est une methode virtuelle,je veux la reimplementer pour ajouter un bouton à mon viewer,et donc je crée une classe Myclasse,qui va heriter de ma classe ExaminerViewer et j'ajoute mon bouton.

    mon problem reside dans l'organisation des fichier,entre MyClass.h,Myclass.h et MyClassP.h (puisque je dois suivre la meme organisation)

    oubien,est ce que je peux utiliser les headers de la meme classe Examinerviewer et pas la peine d'en faire de nouveau pour Myclass(puisque moi au final je reinplemente qu'une methode de cette classe).
    et donc mon Myclass.cpp aura la forme de "class Myclass::public ExaminerVieiwer(){}" etc ..(pas de headers donc)

    j'avoue que je suis un peu confuse,si qu'elqu'un peut m'aider ladessus.
    Merci

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Il est recommandé de n'avoir qu'un fichier .h/.cpp par classe même si ta classe ne spécialise qu'une fonction.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Tunisie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 141
    Points : 59
    Points
    59
    Par défaut
    oui mais dans ce cas,ma classe herite d'une classe mére juste pour réimplementer la methode virtual citée plus haut.et elle aura donc le meme header ou presque que le ExaminerViewerP.h

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Halloula Voir le message
    oui mais dans ce cas,ma classe herite d'une classe mére juste pour réimplementer la methode virtual citée plus haut.et elle aura donc le meme header ou presque que le ExaminerViewerP.h
    Non, elle n'aura pas le même header. Celui de la classe dérivée inclut celui de la classe de base mais ne redéclare pas tout :
    base.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #ifndef base_h
    #define base_h
    class Base
    {
    public: 
        void action()
        { do_action();}
    private:
       virtual do_action();
    };
    #endif /* base_h*/
    derive.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #ifndef derive_h
    #define derive_h
    // classe de base :
    #include "base.h"
    class Derive : public Base
    {
    private:
       virtual do_action(){
          // blablabla
       }
    };
    #endif /*derive_h*/

  5. #5
    Membre averti

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Points : 446
    Points
    446
    Par défaut
    Je suis aussi un peu confus, mais la structure que j'utilise est la suivante:

    1) Un .h et un .cpp pour la classe de base, comme p.ex. "ExaminerViewer.h" et "ExaminerViewer.cpp"
    2) Un .h et un .cpp pour la classe fille comm p.ex. "MyClass.h" et "MyClass.cpp"
    3) Dans le ".h" de la fille, je ne définis que les constructeurs et les fonctions à remplacer, les autres fonctions sont automatiquement héritées de la classe parent. Attention toutefois: le polymorphisme de la classe mère est perdu dès qu'on remplace une fonctions dans la classe fille, si tu as Foo(int) et Foo(double) dans la classe mère, et "Foo(int)" dans la fille, alors Foo(double) et n'est plus valide chez la fille!

    Exemple:

    Maman.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Maman {
      public:
        Maman();
        virtual void Foo(int);
        virtual void Foo(double);
        virtual void Bar(int);
    };
    Fille.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Fille : public Maman {
      public:
        Fille();
        virtual void Bar(int);
    //    virtual void Foo(int);  // Cette fonction cache Foo(double) (mais elles restent accessibles via Maman::Foo())
    //    virtual void Foo(std::string);  // Cette fonction "cache" aussi Foo(int) et Foo(double)
    };
    Maman.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <iostream.h>
    #include <string>
    Maman::Maman() {};
    void Maman::Foo(int a) {
      cout<<"Maman::Foo(int)="<<a<<endl;
    }
    void Maman::Foo(double a) {
      cout<<"Maman::Foo(double)="<<a<<endl;
    }
    void Maman::Bar(int a) {
      cout<<"Maman::Bar(int)="<<a<<endl;
    }
    Fille.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <iostream.h>
    #include <string>
    Fille::Fille() {};
    //void Fille::Foo(std::string a) {
    //  cout<<"Fille::Foo(std::string)="<<a<<endl;
    //}
    //void Fille::Foo(int a) {
    //  cout<<"Fille::Foo(int)="<<a<<endl;
    //}
    void Fille::Bar(int a) {
      cout<<"Fille::Bar(int)="<<a<<endl;
    }
    Utilisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      Fille a;
      a.Bar(10);  // Affiche Fille::Bar(int)=10
      a.Foo(11);  // Affiche Maman::Foo(int)=11
      a.Maman::Bar(12);  // Affiche Maman::Bar(int)=12
    Mais ce comportement serait aussi bon sans le mot-clé "virtual". La virtualité n'est utile que lorsque tu manipules des pointeurs.

    Les fonctions non-virtuelles sont appelées selon le type du pointeur (un pointeur de type "Maman*" appellera toujours les fonctions de "Maman", même si l'objet pointé est une "Fille"). Le lien vers la fonction est déterminé au moment de la compilation.

    Les fonctions virtuelles sont appelées selon le type d'objet réellement pointé par le pointeur (un pointeur de type "Maman*" appellera la fonction "Maman::Bar" ou "Fille::Bar" selon l'objet pointé). Le lien vers la fonction est déterminé au moment de l'exécution selon le type réel de l'objet:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Fille a;
      Maman* c=&a;
      c->Bar(13);  // Affiche Fille::Bar si virtuel, Maman::Bar si non virtuel

Discussions similaires

  1. implementation d'une methode
    Par khaledmoez dans le forum C++
    Réponses: 1
    Dernier message: 06/12/2009, 18h59
  2. Réponses: 1
    Dernier message: 06/11/2009, 00h20
  3. Réponses: 5
    Dernier message: 23/01/2009, 10h52
  4. Réponses: 2
    Dernier message: 25/01/2008, 21h41
  5. [Language]problème lors de l'appel d'une méthode
    Par Samanta dans le forum Langage
    Réponses: 6
    Dernier message: 18/05/2005, 13h03

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