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 :

Cast void* - Objet C++


Sujet :

C++

  1. #1
    Futur Membre du Club
    Inscrit en
    Août 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 5
    Points : 5
    Points
    5
    Par défaut Cast void* - Objet C++
    Bonjour,

    Je travaille actuellement sur un projet en C/C++ dans lequel je souhaite "caster" un membre d'une classe de type void* en un pointeur sur un objet d'une autre classe.
    Je m'explique : j'ai deux classes bien différentes CTest1 (utilisation de singleton) et CTest2 avec fonctions et attributs membres.
    Dans la classe CTest2 j'ai l'attribut suivant :
    Et je désire faire dans le constructeur de la classe CTest2 la chose suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    CTest2::CTest2{
         m_pObjet= (CTest1* )CTest1::getInstance();
         m_pObjet->fonction();
    }
    Seulement voilà, à la compilation j'ai l'erreur '"void*' is not a pointer-to-object type".
    Donc si quelqu'un a une idée pour faire cette manipulation ( en soulignant, que dans mon projet il faut que j'utilise un void* , je ne peux pas par exemple utiliser un attribut membre "CTest1*". )

    Merci d'avance pour vos réponses.

  2. #2
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Bonjour,

    "void*' is not a pointer-to-object type"
    Ceci veux dire: "void* est une adresse brute, comment tu veux que je l'utilise si je connais pas ce que c'est?"

    Fais attention , ton cast est un C-Style. En C++, tu as plusieurs styles de cast à utiliser et jamais de C-Style.
    static_cast, const_cast, dynamic_cast, reinterpret_cast. Je te laisse voir la FAQ http://cpp.developpez.com/faq/cpp/?page=conversions

    Dans ton cas tu dois utiliser le reinterpret_cast, mais je porte ton attention sur le fait que d'utiliser ce cast est très très souvent associé à une mauvaise architecture de ton programme. Généralement, ce type de cast est très utilisé pour les drivers et la programmation très bas niveau. Donc regarde aussi si tu ne peut pas faire autrement.

    Edit: Je note aussi étrange que ton singleton retourne un void* et non pas un objet du type CTest1...
    Homer J. Simpson


  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut et bienvenue sur le forum,

    Pourrais tu déjà nous expliquer pourquoi tu souhaite que ton membre soit un pointeur sur void

    Cela n'a, a priori, aucun sens, surtout si c'est un pointeur qui doit représenter l'instance de ton singleton

    Je confirme ce que dit Astraya: l'utilisation d'un pointeur sur void et du reinterpret_cast est, très souvent, le signe d'un sérieux problème de conception
    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

  4. #4
    Futur Membre du Club
    Inscrit en
    Août 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Tout d'abord merci pour vos réponses.
    Ensuite, ce que je souhaite faire c'est ceci :
    J'ai une classe CAbstract qui est une classe abstraite avec des méthodes virtuelles pures. La classe CTest1 est une classe fille de CAbstract qui va redéfinir les méthodes virtuelles et aussi appeler et utiliser les méthodes de la classe CTest2, classe complètement indépendante des deux autres.
    En sachant qu'il y a plusieurs classes Filles, j'avais dans l’ idée de faire par exemple, un attribut "protected" dans CAbstract que les classes filles pourrait utiliser et "caster" en fonction des autres classes qu'elles utilisent. Chaque classe fille va utiliser, pour redéfinir les méthodes virtuelles, une autre classe. En fait, l'attribut "protected" serait utilisé pour définir un objet, d' où mon intention d'utiliser un pointeur "void*" que je pourrais changer de "type". Après je sais pas si c'est une bonne idée de faire comme ceci.

  5. #5
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Sais tu travailler avec des templates? à ce que j'ai compris cela pourrais arranger ton problème.

    Le truc de Barton-Nackman ( ça ne s'invente pas comme nom ) pourrait résoudre ton problème
    Homer J. Simpson


  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Alors, interroge toi peut être sur la raison qui t'incite à créer une classe abstraite, et donc à déclarer des fonctions virtuelles pures (vu qu'une classe abstraite ne l'est que par la présence de fonction virtuelle pures ).

    Lorsque tu déclares une fonction virtuelle pure, tu dis au compilateur "les classes dérivées doivent présenter telle fonction, mais je ne dispose, dans la classe de base, pas des informations qui me permettront de fournir un comportement minimum pour les classes dérivées".

    Le résultat est que, le compilateur ayant horreur du vide, il interdira de créer une instance de la classe de base pour éviter que tu ne soit tenté d'appeler cette fonction "qui n'a aucun comportement défini".

    Cela signifie essentiellement que chaque classe dérivée arrivera avec... les membres qui permettront de fournir le comportement adéquat.

    Une autre raison pour laquelle tu pourrais vouloir créer une classe abstraite, malgré le fait que les différentes fonctions proposent chacune un comportement minimum, serait que tu estime toi-même que cette classe "n'est pas assez spécialisée" par rapport à l'usage que tu prévois d'en faire, et que tu veux donc éviter que l'utilisateur ne soit tenté d'en créer une instance.

    Tu déclarera alors de destructeur comme fonction virtuel pur, mais tu devra néanmoins l'implémenter pour permettre aux classes dérivées de l'appeler.

    Il n'y a donc absolument aucun intérêt à... essayer de fournir ce membre dans la classe de base, surtout si c'est en essayant de faire en sorte qu'il puisse s'adapter à toutes les situations

    Autrement, tu as peut être une solution alternative qui consiste à te dire que, si tu ne sais pas encore quel est le type de donnée réellement manipulé, tu sais par contre comment tu va le manipuler, y compris pour la classe de base.

    Cela s'accompagne généralement par la constatation du fait que, a priori, une classe qui hérite de la spécialisation pour des pommes de cette classe de base n'a strictement rien à voir avec une classe qui hérite de la spécialisation pour des éléphants de cette classe.

    Il peut y avoir une autre classe de base commune qui intervient, mais celle dont je parle ne fait qu'apporter... une interface supplémentaire.

    C++ permet de suivre un tel raisonnement grâce à la programmation générique, symbolisée par l'utilisation de classes template.

    L'idée est de dire que tu va manipuler un objet de type T (qui peut être n'importe quoi) et de dire exactement ce que tu en fais, sous une forme proche de:
    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
    template <typename T> // je ne sais pas quel type réel est 
                         // représenté par T
    class Base
    {
        public:
            /* mais je sais que je l'utilise pour construire ma classe de base */
            Base(T const & m):m_(m){}
            /* je sais comment il sera manipulé dans foo() */
            void foo()
            {
                /* la manière dont j'utilise T */
            }
        private:
            /* et je sais que ma classe utilise un objet de type T comme membre
             */
            T  m_;
    };
    Comme Truc et Machin représentent deux type différents, si un classe hérite de Base<Truc> et qu'une autre hérite de Base<Machin>, elles feront partie de deux hiérarchies de classes totalement différentes.

    Si, maintenant ces deux classe héritent toutes les deux de AutreClasse (non présentée ici), elles interviendront, effectivement, dans une hiérarchie de classes commune, pas à cause de Base<T>, mais bien à cause de ...AutreClasse.

    Enfin, il y a un dernier aspect relativement curieux (c'est le C de l'idiome CRTP): Dans certaines conditions, tu peux faire hériter une de tes classes de la spécialisation pour cette classe de la classe de base:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /* Je spécialise ma classe de base avec le type de... la classe que j'écris
     * Et ca marche :D
     */
    class Derivee : public Base<Derivee>
    {
        /*...*/
    };
    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

Discussions similaires

  1. Cast IEnumerable objet typé
    Par UoLad dans le forum Linq
    Réponses: 2
    Dernier message: 09/05/2009, 14h26
  2. cast (void*) -> (char)
    Par nicodn02 dans le forum C
    Réponses: 10
    Dernier message: 14/04/2008, 10h02
  3. Instance of et Cast d'objet
    Par tiamat dans le forum Langage
    Réponses: 7
    Dernier message: 28/12/2007, 12h31
  4. cast d'objet parent en classe fille
    Par Plio dans le forum C++
    Réponses: 2
    Dernier message: 05/10/2007, 13h58
  5. Surdéfinition de l'opérateur de cast (void *)
    Par Thierry Chappuis dans le forum C++
    Réponses: 4
    Dernier message: 07/12/2006, 11h21

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