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 :

singleton, polymorphisme, et surcharge de fonction


Sujet :

C++

  1. #1
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut singleton, polymorphisme, et surcharge de fonction
    Salut !

    J' ai 2 classe de base: VFILE et VTEXTURE. VTEXTURE est une classe singleton. J' essaye d' utiliser le tout dans une class DATA qui utilise le polymorphisme. Mais, problème, les methodes des classes que je voulais utiliser polymorphiquement ont des prototypes differents !

    Pour resoudre ce problème, j' ai penssé à la surcharge des methodes. Je m' explique:

    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
     
    class DATA
    {
          public:
          virtual void init(int) = 0;
          virtual void init(float) = 0;
     
          virtual ~DATA() { };
    };
    class VFILE : public DATA
    {
         public:
         void init(int);
    };
     
    class VTEXTURE : public DATA
    {
         public:
         void init(float);
         static VTEXTURE* getInstance();
     
         private:
         VTEXTURE() { };
         static VTEXTURE *instance;
    };
    Mais le compilateur me mets un mesage assez incomprehensible:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    VTEXTURE.cpp: Dans static member function « static VTEXTURE*
       VTEXTURE::getInstance() »:
    VTEXTURE.cpp:10: error: cannot allocate an object of type `VTEXTURE'
    VTEXTURE.cpp:10: error:   because the following virtual functions are abstract:
    DataManager.h:12: error:        virtual void
       DataManager::init(int)

    Merci d' avance.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Le message du compilateur est clair pourtant. Quand dans la classe DATA tu déclares
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    virtual void init(int) = 0;
    virtual void init(float) = 0;
    Tu déclares que DATA est une classe qui ne peut être instanciée, et que toutes les classes (concrètes) qui dérivent de DATA (VFILE et VTEXTURE dans ton cas) doivent proposer une implémentation des méthodes ci-dessus.
    Or dans VTEXTURE et VFILE, les méthodes init(int) et init(float) ne sont pas redéfinie.

  3. #3
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    Ah ok !

    Donc, en fait, pour utiliser le polymorphisme avec des prototypes de fonction differents, c' est impossible car chaque methode de la classe mère doivent être implementé dans les classes filles. Mais comme l' a dit Napoléon ( ), impossible n' est pas francais :o . Donc, il n' y aurait pas un autre moyen d' utiliser le polymorphisme avec des prototypes differents ?


    Merci d'avance.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Tu leur passes un union ?
    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
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Quel sens ça aurait, d'avoir 2 fonctions polymorphes avec un prototype différent ? L'idée du polymorphisme est d'appeler une fonction sans savoir à l'endroit de l'appel quelle sera l'implémentation qui sera sélectionnée. Si une telle fonction a des arguments différents, on est bien obligé à l'endroit de l'appel de savoir quel type d'argument lui passer, et donc il n'y a plus d'intérêt à avoir un appel polymorphe.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    En fait, je vous explique un peu mieux mon problème: j' essaye dans mon prgramme de faire une classe DATA gerant toute les ressources du programme. Ici la classe VFILE s' occupera des fichiers et VTEXTURE s' occupera de mes textures . Le problème est que, vous l' aurez compris, ma classe VFILE n' a besoin que du nom de fichier (string) pour fonctionner, et ma class VTEXTURE a à la fois besoin du nom de fichier à prendre en paramêtre et la valeur à la quelle la texture va être associer (j' utilise OpenGL).

    Donc, l' interet pour moi d' utiliser ici le polymorphisme est un peu comme l' interet des surcharges de fonctions: cela me permettra au futur de ne plus faire attention aux noms de mes fonctions, mais a leurs argument.


    Citation Envoyé par Médinoc
    Tu leur passes un union ?
    En fait, le problème est que je devrais souvent ajouter des classes, donc des prototypes contenant des arguments different. A la fin j' aurais un union quelque peu enorme et pas très "esthetique"


    Donc il n' y a vraiment aucun moyen de changer les prototypes de fonction polymorphiques ?

    Merci d'avance

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Si les données de ton programme se composent de textures et de fichiers, ce n'est pas de l'héritage qu'il faut faire, mais de la composition.
    Ta classe DATA est composées d'instances de textures et d'instance de fichier.
    Si une classe cliente à besoin de données, c'est à la classe DATA qu'elle s'adressera. Charge à la classe DATA de gérer les détails.
    Vouloir faire de l'héritage la où une relation de filiation n'est pas clairement établie amène le plus souvent beaucoup plus de problèmes que cela n'en résoud.

  8. #8
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    Ok, mais en fait, ce que je voulais exprimer avec l' heritage: tous les types de données de mon programme (VFILE+VTEXTURE) sont des ressources (DATA) géré par une classe principale. Ici, en fait, la classe DATA ne sert qu' a simplifier le point d' entré de VFILE et VTEXTURE pour qu' une autre classe s' en charge. UN PEU comme le Design Pattern facade.

    Donc, est-ce une erreur de faire ca ou pas ?

  9. #9
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    A priori, non, mais dans ce cas, la création de tes objets est un point ou tu ne peux pas utiliser l'abstraction, puisqu'elle a besoin d'éléments spécifiques à l'objet en question (c'est souvent le cas, on peut utiliser les objets par un pointeur sur une classe de base partout, sauf quand on les construit). Donc tu peux avoir du code du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    vector<DATA*> vec;
    VFILE * vf = new VFILE;
    // init n'est pas une fonction virtuelle, et n'existe même pas dans DATA
    vf->init("toto"); 
    vec.push_back(vf); 
    // A partir de maintenant, on ne manipule VFILE que par l'intermédiaire de l'interface définie dans DATA
    Sachant que le code suivant est plus classique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DATA *data = new VFILE("Toto");
    // A partir de maintenant, on ne manipule VFILE que par l'intermédiaire de l'interface définie dans DATA
    Rassembler ta fonction init avec le constructeur limite le nombre de fonctions publiques non virtuelles dans VFILE, et simplifie l'écriture, puisqu'il n'y a que pour la création que le type exact est connu.


    Si tu ne veux même pas connaître le type exact lors de la création, regarde du côté des patterns de factory. Dans ce cas, il est plus simple de définir un constructeur avec un paramètre qui est un type commun à tes objets. Medinoc a proposé une union. Je proposerais plus une chaîne de caractères à parser, ou un flux istream, car ce mécanisme apparaît assez souvent quand on crée les VFILE et VTEXTURE à partir de fichiers de données. Dans ce cas, utiliser un véritable framework de sérialisation (comme boost::serialization) peut aussi être envisagé.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  10. #10
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    Ok. Je pense qu' en effet implementer une fonction pour pouvoir utiliser les classes filles de DATA serais trop lourd, je me tourne donc vars la solution d' une string contenant tous les arguments.

    Citation Envoyé par JolyLoic
    Dans ce cas, utiliser un véritable framework de sérialisation (comme boost::serialization) peut aussi être envisagé.
    Si j' ai bien compris la serialisation n' est pas pour enregistrer les membres d' une classe dans un fichier ? Je ne comprends pas très bien pourquoi utiliser cette technique

    Merci d'avance.

  11. #11
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par legend666
    Si j' ai bien compris la serialisation n' est pas pour enregistrer les membres d' une classe dans un fichier ? Je ne comprends pas très bien pourquoi utiliser cette technique
    Si, c'est bien ça. Je l'ai mentionné car la désérialisation est un des principaux exemples d'endroits où l'on veut créer des objets même sans savoir quel est leur type.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Citation Envoyé par legend666
    Ok, mais en fait, ce que je voulais exprimer avec l' heritage: tous les types de données de mon programme (VFILE+VTEXTURE) sont des ressources (DATA) géré par une classe principale. Ici, en fait, la classe DATA ne sert qu' a simplifier le point d' entré de VFILE et VTEXTURE pour qu' une autre classe s' en charge. UN PEU comme le Design Pattern facade.
    Vouloir regrouper toutes l'accès à toutes les données de dans une seule classe pour faire en sorte que les clients n'aient qu'un seul interlocuteur n'est pas une mauvaise idée.
    C'est l'implémentation que tu en proposes qui est bancale. Tu peux faire ce que tu souhaites sans utiliser d'héritage.
    Quelque chose du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class DATA
    public:
      VTEXTURE * getTexture(...);
      VFILE *    getFile(...);
    private:
      TextureLoader * m_textureLoader;
      FileLoader *    m_fileLoader;
    Ainsi, chaque autre classe de ton programme qui nécessite une texture ou un fichier passe par DATA, et ignore comment ces données sont chargées.
    A la charge de DATA d'encapsuler les détails, et surtout de rediriger les demandes vers les bons objets.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    VTEXTURE * DATA::getTexture(...) {
      m_textureLoader->getTexture(...);
    }

Discussions similaires

  1. Difference entre polymorphisme et surcharge
    Par Pragmateek dans le forum C++
    Réponses: 15
    Dernier message: 22/03/2006, 00h55
  2. surcharge de fonction
    Par BigNic dans le forum C++
    Réponses: 2
    Dernier message: 21/03/2006, 18h57
  3. API HOOK, Dump dll, Surcharge de Fonction
    Par MicroAlexx dans le forum Windows
    Réponses: 2
    Dernier message: 30/12/2005, 10h39
  4. [MFC] Surcharger des fonctions de CView
    Par Philippe320 dans le forum MFC
    Réponses: 2
    Dernier message: 22/11/2005, 21h24
  5. Surcharge de fonction d'un edit dynamique
    Par Tartar Ukid dans le forum C++Builder
    Réponses: 4
    Dernier message: 13/10/2003, 11h56

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