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 :

Recuperer le type d'une variable.


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre habitu�
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    10
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 10
    Par d�faut Recuperer le type d'une variable.
    Bonjour,

    D'abord desole si mon probleme est un peu tordu ...

    Je souhaiterais recuperer le type T d'une variable, sachant que je ne connais que sa classe mere (donc je ne connais pas le "vrai" type de la variable, etant derive de cette classe mere). Cela me servirais pour incrementer un pointeur sur T.

    Concretement, je souhaiterais faire ceci:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void
    example (std::vector<Vertex*> tableau)
    {
      void* ptr = ...;
     
      inc_pointer<void*, typeof (tableau[42])> (ptr); 
      // ptr pointe maintenant sur la case suivante
    }
    Pour l'instant, j'arrive a faire cela via cette classe templatee (is_pointer est un trait...), mais en donnant explicitement le type d'arrive (donc sans l'extraire d'une variable comme je souhaiterais):
    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
     
    template<typename SrcPtr, typename DstPtr>
    void 
    Pointer::inc_pointer (SrcPtr& ptr)
    {
      if (Pointer::is_pointer<SrcPtr>::result && Pointer::is_pointer<DstPtr>::result)
        ptr = &(((DstPtr) ptr)[1]);
      else
        // erreur
    }
     
    void
    exemple ()
    {
      void* ptr;
     
      Pointer::inc_pointer<void*, TypeDeDestination*> (ptr);
    }
    Quelques precisions:
    • etant sous visual studio 2008, je n'ai pas acces a typeof (dailleurs qui n'est pas portable, non ?)

    • Je prefererais ne pas templater la fonction ou j'ai besoin d'incrementer mon pointeur, ca n'aurait pas de sens au niveau du role de la fonction

    • Eviter la solution crade du switch (code intrusif)

    • Je fais ca dans le cadre d'une fonction de rendu en DirectX9. C'est pour faire des memcpy de chaque vertex ecrit dans mon vertex buffer, donc il n'y a pas de problemes d'allocations ou des possibilites de violation d'acces...


    Merci d'avance pour l'aide que vous pourrez apporter !

    Altefquatre

  2. #2
    boli_971
    Invit�(e)
    Par d�faut
    Salut,
    En C++ il existe l'op�rateur typeid(type) si sa peut t'aider.

    Exemple d'utilisation:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    int main(int argc, char* argv[])
    {
    int var = 2009;
    if(typeid(var) == typeid(int))
       std::cout << "var est un int";
     
    }

  3. #3
    Membre habitu�
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    10
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 10
    Par d�faut
    Salut,

    J'avais lu 2 ou 3 trucs sur typeid, mais a la fin, ca reviens a faire un switch:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    switch (typeid (variable))
    {
    case typeid (MonType1):
      // traitement
      break;
    case typeid (MonType2):
      // traitement
      break;
    case typeid (MonType3):
      // traitement
      break;
    // etc...
    };
    Meme si ca marche, je souhaiterais faire du code plus generique et non intrusif comme je disais (je suis oblige de rajouter un cas si je cree un nouveau type). Dans l'ideal, ce serait quelque chose dans le style template / metaprogrammation.

    Merci quand meme de ta reponse.

  4. #4
    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
    La grande question �tant: pourquoi tu as besoin d'un pointeur de type void ?
    Pourquoi ne pas utiliser un pointeur de type Vertex ? Ou mieux, un iterateur ?
    "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)

  5. #5
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,

    D'abord, j'aimerais savoir pourquoi tu veux incr�menter le pointeur, parce ce que �a risque de t'apporter des probl�me sans noms que de faire pointer ton pointeur sur l'adresse qui suit celle � laquelle se trouve ton objet

    De la m�me mani�re, d�cider d'utiliser comme param�tre template un pointeur sur void me parrait toujours suspect...

    G�n�ralement, si tu veux pouvoir manipuler le type r�el d'une classe template, il s'agit d'utiliser une classe template proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <typename T>
    class MyClass
    {
        public:
            typedef T Type;
            typedef T& TypeRef;
            typedef T const & ConstTypeRef;
            typedef T* TypePtr;
            /*...*/
    };
    avec un exemple simple d'utilisation:
    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
    int main()
    {
     
        /* Nous pouvons accéder à une instance, à une référence
         * constante ou non et à un pointeur de n'importe quel type */
        MyClass<int>::Type var =0;
        MyClass<int>::TypeRef ref =var;
        MyClass<int>::TypePtr ptr = &var;
        MyClass<int>::ConstTypeRef constref = var;
        cout<< "avant incrementation par var "
            <<"var = "<<var<<" ref = "<<ref<<" constref = "
            <<constref<<" ptr ="<<ptr<<endl;
        var++;
        cout<<"apres incrementation par var "
            <<"var = "<<var<<" ref = "<<ref<<" constref = "
            <<constref<<" ptr ="<<ptr<<endl;
        ref++;
        cout<<"apres incrementation par ref "
            <<"var = "<<var<<" ref = "<<ref<<" constref = "
            <<constref<<" ptr ="<<ptr<<endl;
        /* constref++; serait refusé */
        return 0;
    }
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  6. #6
    Membre habitu�
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    10
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 10
    Par d�faut
    Desole si je suis assez locace, j'espere que ca repondra a vos questions...

    D'abord, j'aimerais savoir pourquoi tu veux incr�menter le pointeur
    En fait, comme je disais, c'est pour une fonction de rendu en directX, au niveau des vertex buffers.
    Si j'utilise un void*, c'est parce que la fonction Lock utilise un void** pour donner un pointeur (&vbuff) vers une zone memoire ou on peut inscrire nos vertice (vertex_size est un sizeof du type final de vertex, mais la j'utilise un switch juste pour pallier a mon probleme).

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    if (FAILED (hr = vb->Lock (0, vertice.size () * vertex_size,
                                        &vbuff, 
                                        D3DLOCK_DISCARD)))
        // erreur
    Ensuite, je fais des memcpy de chaque vertex sur la zone memoire en question:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    for (unsigned int i = 0; i < vertice.size (); ++i)
    {
      memcpy (vbuff, vertice[i], vertex_size);
     
      vbuff++; // on passe a la case suivante dans la zone memoire allouee par Lock
    }
    En principe, si Lock fait bien son boulot, il devrait retourner un pointeur vers une zone memoire valide, donc il ne devrait pas y avoir de probleme de memoire/addresses...

    De la m�me mani�re, d�cider d'utiliser comme param�tre template un pointeur sur void me parrait toujours suspect...
    Effectivement, j'aurais pu utiliser un Vertex*, mais ca reviendrait au meme sachant que je n'utilise pas les Vertex* mais des types derives uniquement.

    Apres ma hierarchie de classes pour les vertice est discutable, etant donne qu'il n'y a pas de fonction en virtual pour le polymorphisme (ex: pas de destructeur, car inutile ici)...
    En fait c'est plus des struct dans le sens C, c'est-a-dire que je n'ai uniquement que des champs. Si je souhaite eviter les methodes, c'est pour pouvoir faire des sizeof et des memcpy valides dans mon vertex buffer. (a chaque fois que je rajoute une methode, ca rajoute 4 octets a la classe et a ses derivees... 1 methode => 1 pointeur sur fonction ?).

    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
     
    class Vertex
    {
    public:
      Vertex (float x = 0, float y = 0, float z = 0);
     
      float x, y, z;
    };
     
    class Vertex3d : public Vertex
    {
    public:
      Vertex3d (float x = 0, float y = 0, float z = 0, 
                unsigned int r = 0, unsigned int g = 0, unsigned int b = 0);
     
      DWORD colour;
    };
     
    class Vertex2d : public Vertex
    {
    public:
      Vertex2d (float x = 0, float y = 0, float z = 0, 
                unsigned int r = 0, unsigned int g = 0, unsigned int b = 0);
     
      float rhw;
      DWORD colour;
    };
     
    class TexVertex2d : public Vertex2d
    {
    public:
      TexVertex2d (float x = 0, float y = 0, float z = 0,
                   float tu = 0, float tv = 0,
                   unsigned int a = 255, 
                   unsigned int r = 255, unsigned int g = 255, 
                   unsigned int b = 255);
     
      float tu;
      float tv;
    };
    Merci pour vos reponses

  7. #7
    Membre habitu�
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    10
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 10
    Par d�faut
    Bon et bien, si ca n'inspire pas grand monde, c'est que je me complique peut-etre trop la vie... Je crois que je vais rester sur un switch, vu que ca marche tres bien malgre l'aspect intrusif du code...

    Si ca peut interesser quelqu'un, voila grossierement comment je procede:
    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
    // get_size renvoit une taille en octets en fonction d'un argument
    size_t
    get_size (DWORD fvf_format)
    {
      switch (fvf_format)
      {
      case 1:
        return sizeof (Type1);
        break;
      case 2:
        return sizeof (Type2);
        break;
      // etc...
      }
    }
     
    void
    example (std::vector<Vertex*> vertice, DWORD fvf_format)
    {
      size_t vertex_size = get_size (fvf_format);
      char* vertex_buffer = NULL;
     
      // du code ...
      // initialisation de vertex_buffer sur une zone memoire valide
     
      // on copie chaque vertex
      for (int i = 0; i < vertice.size (); ++i)
      {
        memcpy (vertex_buffer, vertice[i], vsize);
     
        vertex_buffer += vsize;
      }
     
      // du code...
    }
    La raison du char* est qu'un char est sur 1 octet, et comme sizeof renvoit une taille en octets, si on a un type T de 5 octets par ex, pour aller a la case suivante de type T, c'est comme si on se deplacait de 5 cases de type char... (bon ok, c'est de la bidouille crado mais ca marche... :S)

    Merci de vous etre interesse a ce probleme.

Discussions similaires

  1. determiner le type d'une variable
    Par Mokhtar BEN MESSAOUD dans le forum Langage
    R�ponses: 1
    Dernier message: 14/03/2006, 17h11
  2. [VBA-E]Renvoyer le type d'une variable
    Par alexxx69 dans le forum Macros et VBA Excel
    R�ponses: 4
    Dernier message: 15/02/2006, 18h07
  3. R�ponses: 2
    Dernier message: 19/01/2006, 21h59
  4. Connaitre le type d'une variable
    Par mic79 dans le forum Langage
    R�ponses: 2
    Dernier message: 04/01/2006, 15h42
  5. Changer el type d'une variable sql sous postgre8/admin
    Par smag dans le forum PostgreSQL
    R�ponses: 2
    Dernier message: 24/08/2005, 12h31

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