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 :

Un cast de SmartPointer qui pose probléme


Sujet :

C++

  1. #1
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut Un cast de SmartPointer qui pose probléme
    Bonjour,

    Je suis en train de développer une fonction sur une classe SmartPointer que j'ai déja développer.

    Cette fonction à pour but de retouner un smartPointer d'un autre Type mais partageant le meme pointeur que le premier. Je m'en sert pour le polymorphisme.

    Ma fonction marche très bien sauf que si je concerve certaines données en private ca compile pas avec cet erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ../library/libutils/smartpointer.h:254: error: 'SDLWidget* SmartPointer<SDLWidget>::ref' is private
    ../library/libutils/smartpointer.h:139: error: within this context
    ../library/libutils/smartpointer.h:255: error: 'unsigned int* SmartPointer<SDLWidget>::refCount' is private
    ../library/libutils/smartpointer.h:140: error: within this context
    voici ma 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
     
    template <class X>
    SmartPointer<X> Cast(SmartPointer<T> &_smartPointer, X* _dummy)
    {
    	SmartPointer<X> newSmartPointer;
     
    	mModRef.Lock();
    	newSmartPointer.ref = (X*)_smartPointer.ref;
    	newSmartPointer.refCount = _smartPointer.refCount;
    	*refCount++;
    	mModRef.Unlock();
     
    	return newSmartPointer;
    }
    Aparemment le probleme c'est que dans ce cas les variables ref et refCount deviennent privée pour la meme classe à cause du template.

    J'ai essayer de résoudre mon probleme en ajoutant un :
    friend class Smartpinter; (ce qui est bizard dans la classe smarpointer dailleur) mais ca marche pas...

    En attendant je met tout en public mais j'aurais aimé trouver une solution plus propre à ce probleme...

    Quelqu'un à une idée ???

    Merci
    J'aime pas les épinards... Mais alors pas du tout

  2. #2
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Amitié et templates ne marchent pas toujours très bien d'un compilo à l'autre.
    Quelle syntaxe tu avais utilisé pour déclarer ta fonction amie ?

    Ensuite, C<X> et C<Y> ne sont pas les mêmes classes. Ce qui explique qu'être ami avec Cast<SmPtr>, ce n'est pas comme être ami avec Cast<SmPtr<U> >.

    Tu as regardé chez boost pour voir comment ils avaient procédé ?
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  3. #3
    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
    Partant du principe que le fonctionnement de base de tes 'smarts pointers' ne dépendent pas du type du pointeur encapsulé, je te suggère de faire ce que l'on fait classiquement dans ce cas : créer une classe de base, non template, regroupant ces fonctionnalités.
    C'est notamment le cas dans les implémentations classique des conteneurs dans la STL.
    Cette classe de base commune à toutes tes instanciations de template te permettra de faire ce que tu souhaites.
    L'exemple que je joins est loin d'être parfait. Il est juste là pour illustrer
    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
    //-- HEADER
    class SmartBase
    {
    public:
      ~SmartBase();
     
    protected:
      SmartBase(void * ptr);                                                                                                                                                            
      SmartBase(const SmartBase& other);
     
      int * refCount_;
      void * ptr_;
    };
     
    //-- SOURCE
     
    SmartBase::SmartBase(void * ptr)
      : ptr_(ptr)
    {
      refCount_ = new int();
      *refCount_ = 1;
    }
     
    SmartBase::~SmartBase()
    {
      if (*refCount_ == 0)
        delete refCount_;
    }
     
    SmartBase::SmartBase(const SmartBase& other)
    {
      ptr_ = other.ptr_;
      refCount_ = other.refCount_;
      ++(*refCount_);
    }
    Cette classe de base est 'abstraite' au sens de la conception. Elle ne peut être directement instanciée (d'où l'ensemble des constructeurs déclaré comme protégé).
    Ensuite ta classe SmartPtr à proprement parler en hérite :
    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
    //-- HEADER
    template<typename T>
    class SmartPtr : public SmartBase
    {
    public:
     
      typedef T value_type;                                                                                                                                                 
      typedef T * pointer;
     
      SmartPtr(T* ptr);
      SmartPtr(const SmartPtr& other);
      template<typename U> SmartPtr(const SmartPtr<U>& other); // L'opérateur de CAST en question
      ~SmartPtr();                      
      pointer ptr() const;                                                                                                                                        
    };
     
    //-- SOURCE
     
    template<typename T>
    SmartPtr<T>::SmartPtr(T* ptr)
      :  SmartBase(ptr)
    {
    }
     
    template<typename T>
    SmartPtr<T>::~SmartPtr()
    {
      if (!--(*refCount_))
        delete reinterpret_cast<T*>(ptr_);
    }
     
    template<typename T>
    SmartPtr<T>::SmartPtr(const SmartPtr<T>& other)
      : SmartBase(other)
    { }
     
    template<typename T>
    template<typename U>
    SmartPtr<T>::SmartPtr(const SmartPtr<U>& other)
      : SmartBase(other)
    {
      static_cast<typename SmartPtr<T>::pointer>(other.ptr());
    }
    Le static cast
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static_cast<typename SmartPtr<T>::pointer>(other.ptr());
    est un moyen de s'assurer que la construction d'un SmartPointer à partir d'un autre se fait uniquement uniquement si le smart pointer construit est d'un type plus générique. Si ce n'est pas le cas, la compilation échouera.
    Il existe d'autres moyens plus propre de s'en assurer, cf Modern C++ Desgin de Andrei Alexandrescu.

    HTH

  4. #4
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    Nikel ca marche ! Merci !
    J'aime pas les épinards... Mais alors pas du tout

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. insert select qui pose problème
    Par vgaudin dans le forum SQL
    Réponses: 3
    Dernier message: 21/09/2007, 09h07
  2. [VBA]: Nom de champ qui pose problème
    Par Amitom dans le forum Access
    Réponses: 4
    Dernier message: 07/06/2007, 09h26
  3. [D5] Transtypage qui pose problème
    Par MelkInarian dans le forum Delphi
    Réponses: 4
    Dernier message: 06/04/2007, 16h38
  4. requete update qui pose problème
    Par kirian dans le forum Requêtes
    Réponses: 2
    Dernier message: 26/02/2007, 11h20
  5. code qui pose problème
    Par onePersonne dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 15/10/2006, 14h27

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