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

Langage C++ Discussion :

Alternative au template de methode virtuelle pure


Sujet :

Langage C++

  1. #1
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2
    Par défaut Alternative au template de methode virtuelle pure
    Bonjour,

    Avant de me faire assassiner sur ce forum, je sait que l'on ne peut pas creer de template de methode virtuelle. Mon problème est que la plupart des alternatives que j'ai eu l'occasion de trouver sur le net ne semble pas fonctionner avec moi, et je voulait votre aide sur la question car c'est un problème vraiment énervant.
    Voici mon problème: j'ai une application qui charge tous les modules d'un repertoire a la volée (durant l'execution) a grand coup de dlopen. Cela permet aux utilisateurs de creer leurs propres modules si ils le souhaitent.
    Pour ce faire j'utilise une classe abstraite, qui sert de canevas aux modules. l'une de ses classes virtuelle pure est un getter qui reçoit en parametre le nom d'une variable, et reçoit en retour la valeur de cette variable. Cette variable peut etre de n'importe quel type, c'est pourquoi j'ai pensé aux Templates, pour découvrir cela ne marche pas et ne marchera jamais, idem pour sa version "crade" du void *. les surcharges sont hors de question afin d'eviter au developpeur du module de devoir toutes les implementer dans son module.
    P.S.: le module que j'essaie d'implementer afin de tester mon gestionnaire de module parse un fichier, etablie le typage pour chaque ensemble clé/valeur, et renvoie a l'appelle de la methode getValue(clé) la valeur dans son typage correcte (clé => width / valeur => int, clé => path / valeur => std::string, clé => coord, valeur => float, etc...).
    J'espere avoir été assez clair, vu que je voit quel code de mon prog poster pour expliquer ce que je souhaite faire...

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Regarde du coté de boost::any et du type-erasure pour pouvoir renvoyer un objet qui peut prendre n'importe quelle valeur. Il faut juste que les méthodes appelantes connaissent le type de l'objet quelle devrait recevoir pour que le cast ait se passe sans problème.

    PS/ Cela fait longtemps que je n'ai pas trituré des DLL, donc un bout de code démonstratif serait le bienvenu pour que je puisse affiner ma réponse.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2
    Par défaut
    Merci pour cette reponse, cependant je n'utilise pas Windows mais Unix (NetBSD pour etre plus exact), mais dans le cas présent la seule différence est la manière de charger en mémoire les bibliothèques dynamiques (dlopen() pour les systèmes Unix et Linux, et une autre fonction pour Windows dont j'ai oublié le nom).

    quant au code il est disponible sur sourceforge (chercher gaiaproject). mais voici des extraits:
    le canevas pour les modules gérants les fichiers (on peut d'ailleurs voir le void * crade que je vais m'empresser de tenter de remplacer par boost::any):
    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
     
    #ifndef __FILE_HPP__
    #define __FILE_HPP__
     
    #include <string>
     
    #include "../../kernel/plugin.hpp"
     
    class	File : public PlugIn
    {
    public:
      File() {};
      virtual void *getValue(std::string key) = 0;
      virtual ~File() {};
    };
     
    #endif // __FILE_HPP__
    la classe plugin dont herite tous les canevas:
    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
    #
    ifndef __PLUGIN_HPP__
    #define __PLUGIN_HPP__
     
    #include <string>
     
    class PlugInManager;
     
    class			PlugIn
    {
    public:
      PlugIn() {};
      virtual std::string	getId() = 0;
      virtual int		Initialise() = 0;
      virtual void		Refresh() = 0;
      virtual ~PlugIn() {};
    };
     
    typedef PlugIn	*Create_t();
    typedef void	Destroy_t(PlugIn *);
    #endif // __PLUGIN_HPP__
    et enfin l'interface d'un module qui sera chargé de fournir plusieurs informations sur les dossiers du proj' (encore une fois, le void * doit disparaitre...):
    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
     
    #ifndef __DIRECTORY_HPP__
    #define __DIRECTORY_HPP__
     
    #include "../../Managers/FileManager/file.hpp"
    #include <string>
     
    class		Directory : public File
    {
    private:
      std::string	homedirectory;
      std::string	installationdirectory;
      std::string	id;
     
    public:
      Directory();
      std::string	getId();
      void		*getValue(std::string key);
      int		Initialise();
      void		Refresh();
      ~Directory();
    };
     
    extern "C" PlugIn	*Create()
    {
      return (new Directory);
    }
     
    extern "C" void		Destroy(PlugIn *p)
    {
      delete p;
    }
     
    #endif // __DIRECTORY_HPP__

Discussions similaires

  1. Templates & methods virtuels : La feinte parfaite ?
    Par Niklaos dans le forum Langage
    Réponses: 3
    Dernier message: 27/10/2009, 19h10
  2. Réponses: 4
    Dernier message: 09/10/2008, 09h04
  3. Réponses: 2
    Dernier message: 02/10/2008, 16h37
  4. [debutant] probleme avec methode virtuelle pure
    Par Treuze dans le forum Débuter
    Réponses: 10
    Dernier message: 21/04/2006, 12h58
  5. Réponses: 19
    Dernier message: 10/02/2005, 22h43

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