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 :

[Template] MetaProg : Conna�tre le type point� d'un pointeur de membre


Sujet :

C++

  1. #1
    Membre �prouv�
    Profil pro
    Inscrit en
    F�vrier 2004
    Messages
    1 825
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 1 825
    Par d�faut [Template] MetaProg : Conna�tre le type point� d'un pointeur de membre
    Bonjour,

    Tout d'abord, j'ai peu d'espoir de trouver une solution. Voici mon probl�me :

    J'ai un composant qui a ses propres types, r�f�renc�s par une �num�ration, que je dois utiliser. Puis des propri�t�s typ�es :
    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
     
    enum COMPO_TYPE
    {
        INT = 0,
        FLT,
        STR,
        DBL,
        NONE
    };
     
    class IProperty
    {
    public:
       COMPO_TYPE GetCompoType() = 0;
    };
     
    template<class T>
    struct SCOMPO_HELPER
    {
       enum { VALUE = NONE };
    };
     
    template<>
    struct SCOMPO_HELPER<typename int>
    {
       enum { VALUE = INT };
    }
     
    template<>
    struct SCOMPO_HELPER<typename float>
    {
       enum { VALUE = FLT };
    }
     
    template<>
    struct SCOMPO_HELPER<typename double>
    {
       enum { VALUE = DBL };
    }
     
    template<>
    struct SCOMPO_HELPER<typename char*>
    {
       enum { VALUE = STR };
    }
     
    template<class T>
    class CProperty
    {
       // des méthodes
       COMPO_TYPE GetCompoType()
       {
           return SCOMPO_HELPER<T>::Value;
       }
    };
    Jusque l�, tout vas bien. Mon composant utilise un tableau. Pour construire chaque colonne, il faut sp�cifier le type de cette colonne.
    Pour trouver le type de la colonne, je prends la premi�re instance de mon type d'objet � repr�senter, puis je parcours ses propri�t�s et je fais :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    IProperty* prop = RécupèreLaPropriété(monObjet, index);
    m_composant.AddColonne(prop->GetCompoType(), strLibellé);
    Sauf qu'admettons que je n'ai encore aucun objet instancier pour pouvoir r�cup�rer le premier, et ensuite les types de ses propri�t�s pour construire les colonnes du tableau, je ne peux rien faire.

    Or, je connais le type de l'objet, et je peux r�cup�rer des pointeurs de membres sur celui-ci, sous forme de "IProperty CUneClasse::*member".

    Est-ce que je peux bidouiller un truc pour r�cup�rer le type r�el de "CUneClasse::*member", sans aucune instance, et ensuite ci possible le param�tre template ?

    Au pire, je r�cup�re le type r�el, je l'instancie pour ex�cuter sa m�thode GetCompoType() ?


    Ayant lu quelques trucs sur la m�ta programmation, j'me dis que peut-�tre il y a une solution � �a ?


    Merci beaucoup,

    Bonne soir�e

  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
    Par d�faut
    Salut,
    [pr�ambule]Que CProperty n'h�rite pas de IProperty est une erreur de copier/coller?[/pr�ambule]
    Comment est d�finit la classe de monObjet? Si les propri�t�s sont un tableau dynamique, tu ne peux conna�tre le type qu'avec une instance. Sinon, je pense qu'il faut que tu nous montre un exemple de ce type de classe.
    A l'aveuglette, je dirais que peut-�tre tu peux trouver des pistes du c�t� de Boost.Preprocessor?

  3. #3
    Alp
    Alp est d�connect�
    Expert confirm�

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par d�faut
    Citation Envoy� par mister3957 Voir le message
    Est-ce que je peux bidouiller un truc pour r�cup�rer le type r�el de "CUneClasse::*member", sans aucune instance, et ensuite ci possible le param�tre template ?
    Une classe de traits ?

  4. #4
    Membre �prouv�
    Profil pro
    Inscrit en
    F�vrier 2004
    Messages
    1 825
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 1 825
    Par d�faut
    Oui oui, c'est une erreur de copier/coller, CProperty<T> h�rite bien de IProperti*

    Un exemple de donn�e metier :
    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
     
    // définitions de type en amont
    typedef CProperty<std::string> TStringProperty;
    // pareil avec long, int, uint, ulong etc..
     
    class CClient
    {
    public:
       const TULongProperty& GetIdent() const { return m_ulIdent; }
       const TStringProperty& GetName() const { return m_strName; }
     
    private:
       TULongProperty m_ulIdent;
       TStringProperty m_strName;
    };
     
    // Et j'ai une classe trait pour enregistrer les propriétés :
    template<class T>
    struct SPropertyRegistrer
    {
        static void Do();
    };
     
    template<> SPropertyRegistrer<CClient>::Do()
    {
        GesManager.RegisterProperty<CClient>(&CClient::m_ulIdent);
    }
    J'enregistre les propri�t�s aupr�s du gestionnaire, en les r�f�ren�ant par un pointeur de membre pour �viter de trop consommer la m�moire en les enregistrant � l'�chelle des instances.
    Pour r�cup�rer une propri�t�, je fais
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
        GesManager.GetDataProperty(monClient, "ID"); // renvoi un IProperty*
    L'enregistrement aupr�s du gestionnaire va caster le membre en "IProperty CClient::*" avant de le stocker dans une map avec l'identifiant pass� comme cl�.

    Dans un fichier XML, j'ai les correspondance entre les identifiants de properi�t�s, et les libell� des colonnes correspondantes. Donc je fais :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    CClient* pData = GesManager.GetData<CClient>(0);
     
    // Parcours des correspondances pour arriver à ce genre de chose :
    IProperty* pProperty = GesManager.GetDataProperty(*pData, "ID");
    m_composant.AddColonne(pProperty->GetCompoType(), "Identifiant");
    Voil�, je suis donc oblig� d'obtenir une instance quelque part pour r�cup�rer sa propri�t� et en conna�trele type correspondant du composant.

    Etant donn� que je r�cup�re un IProperty*, ou bien � la limite un IProperty CClient::*, je ne sais pas si une classe Trait pourrait convenir, puisque pour �a passera toujours dans MaClassTrait<IProperty> m�me si en fait c'est une StringProperty ou IntProperty n'est-ce pas ?

    Je vais regarde pour Boost.Preprocessor,


    Merci,

    A bient�t

  5. #5
    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
    Par d�faut
    Je pense que Alp pensait � une classe trait sur CClient par sur IProperty.
    Ensuite, selon le temps que tu peux passer dessus (), Boost.MPL peut certainement aussi r�pondre � ton probl�me.

  6. #6
    screetch
    Invit�(e)
    Par d�faut
    dans le concept, c'est dommage que les propri�t�s ne soient pas de reelles propri�t�s mais les valeurs. Tu essayes de faire du RTTI mais le concept de RTTI est souvent :

    - il y a des classes (RTTIClass)
    - des proprietes (RTTIProperty)
    - (optionnel) des methodes (RTTIMethod) finalement assez proche des proprietes

    Pour chaque classe C++ qui a un RTTI, il existe une instance de RTTIClass, laquelle contient des RTTIProperty et des RTTIMethod

    une RTTIProperty ne contient aucune valeur, mais permet de retrouver la valeur quand on lui donne une instance, de sorte que meme sans instance, tu peux acceder aux proprietes (mais pas aux valeurs)

    soit :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CClient
    {
      static RTTIClass s_metaclass;
      int m_memberInt;
    public:
      static const RTTIClass* metaclass;
      CClient();
    };
     
    RTTIClass CClient::s_metaclass("CClient", RTTIProperty<CClient,int>(offsetof(CClient::m_memberInt)); // TODO : si tu as de l'heritage, les metaclasses doivent avoir cette notion d'heritage
    RTTIClass* CClient::metaclass = &CClient::s_metaclass;
    c'est un exemple evidemment de syntaxe, ca pourrait etre different (ca devrait)
    ensuite, pour recuperer une propriet�, tu passes par
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    IProperty* p = CClient::metaclass->getProperty("name"); //pas d'instance
    et enfin, pour recuperer la valeur :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    p->as<int>()->getValue(instance);
    c'est comme ca que la plupart des langages avec introspection fonctionnent, et tu pourrais meme faire un pont entre C# (mono) et ton RTTI ou encore python ou lua, car ils utilisent les memes concepts (tu aurais un mapping presque parfait entre leur RTTI et le tiens)

  7. #7
    Alp
    Alp est d�connect�
    Expert confirm�

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par d�faut
    Et effectivement encore 3DArchi, je sugg�rais une classe de trait s'occupant des clients. C'est tr�s facile et rapide � mettre en place et s'il y a un soucis tu le sauras � la compilation, donc � mon avis :

  8. #8
    Membre �prouv�
    Profil pro
    Inscrit en
    F�vrier 2004
    Messages
    1 825
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 1 825
    Par d�faut
    Cette histoire des RTTIClass et RTTIProperty au final contiennent une instance (static) de RTTIClass et des RTTIProperty qui la contiennent.

    Par �a, je comprends que les donn�es m�ta sont dissoci�es des donn�es m�tiers n'est-ce pas ?

    Ma classe client �tant en fait de cette forme :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    template <class T>
    CIdentData<T>
    {
     
    };
     
    class CClient : public CIdentData<CClient>
    {
     
    };
    Donc si je ne veux pas rentrer dans du RTTI perso, je peux faire :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    template <class T>
    CIdentData<T>
    {
        static T s_OneData;
    };
     
    T CIdentData<T>::s_tTypeData();
     
    IProperty* p = GesManager.GetDataProperty(CIdentData<CClient>::s_OneData, "name");
    C'est le m�me principe (un peu plus brutalement) ou j'ai loup� quelque chose ?


    Merci

  9. #9
    screetch
    Invit�(e)
    Par d�faut
    C'est le meme principe, mais il faut alors que ton objet property ne soit qu'une couche suppl�mentaire qui permet de retrouver la valeur quand on lui donne l'instance, mais sinon c'est ca. mais c'est quoi le GesManager ?

  10. #10
    Membre �prouv�
    Profil pro
    Inscrit en
    F�vrier 2004
    Messages
    1 825
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 1 825
    Par d�faut
    Ok tr�s bien, je vais faire un objet T static, constant pour �viter d'effectuer des op�rations dessus qui ne soient pas constantes, puis on verra.

    Alors en fait le GesManager c'est un singleton qui poss�de une hi�rarchie �parpill�e regroupant les "GesIdentData<T>".

    Pour chaque type de donn�e, j'aurai un gestionnaire permettant de les charger, les stocker, appliquer les modifs et les supprimer. Un gestionnaire r�f�rence �galement les propri�t�s des donn�es (map<string, IProperty T::*), les propri�t�s identifiantes (vector<string>), puis les relations entre les entit�s (1-0/1, 1-n) en enregistrant.

    Et donc le GesManager a �t� fait pour �viter de tomber dans la singletonite, disons que c'est le point d'entr� vers les gestionnaires de donn�es.

    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
     
    template <class T>
    struct SGesHolder
    {
        CGesIdentData<T>
    };
     
    typedef TTYPELIST_3(CCustomer, CVehicle, CProduct) TGesList;
     
    class CGesManager : public CSingleton<CGesManager>, public CScatteredHierarchy<TGesList, SGesHolder>
    {
        template<class T> void Load()
        {
             SGesHolder<T>::Ges/Load();
        }
     
        // Etc pour les autres méthodes des ges
    };
     
    #define GesManager CGesManager::Instance()
    Et ensuite � l'utilisation :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    GesManager.Load<CCustomer>();
    Et c'est encore plus pratique lorsqu'une fonction utilise le type du template :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    CCustomer monClient;
    CVehicle monVehicule;
     
    GesManager.Delete(monClient);
    GesManager.Delete(monVehicule);

Discussions similaires

  1. Conna�tre le type d'un template
    Par jfouche dans le forum Langage
    R�ponses: 3
    Dernier message: 04/08/2011, 15h09
  2. Conna�tre le type du template
    Par Flo. dans le forum Langage
    R�ponses: 13
    Dernier message: 20/02/2008, 04h26
  3. Conna�tre le type d'un champs d'une table Mysql
    Par xoran dans le forum Langage SQL
    R�ponses: 1
    Dernier message: 20/07/2005, 09h29
  4. [POO] Comment conna�tre le type d'un objet
    Par zizou39 dans le forum G�n�ral JavaScript
    R�ponses: 3
    Dernier message: 01/03/2005, 09h46
  5. [Access] Conna�tre le type de donn�e
    Par Ric1983 dans le forum Bases de donn�es
    R�ponses: 4
    Dernier message: 15/02/2005, 19h09

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