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 :

SmartPointer non fonctionnel


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut SmartPointer non fonctionnel
    Bonjour à tous,

    J'ai développez il y a quelques temps une classe de smart pointer de type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <class T>
    class CSmartPointer
    {
            T   *m_Pointer;
            int *m_Counter;
    };
    J'ai déjà eu l'occasion de faire quelques tests, il "semblerait" qu'ils soient fonctionnels. J'ai pu lire que dans mon cas de figure seul les références circulaires empêchées les smarts pointers de fonctionner. Or j'ai découvert un bug plutôt "étrange" (tout du moins incompris de moi). Voilà le détail de ce qui se passe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class CSceneManager{
         //...
         bool ReadScene(std::string const &Filename);
         bool ReadScene(CNodePtr Root);
         CNodePtr m_Root;
    }
    Il faut savoir que CNodePtr est donc de type CSmartPointer<CNode> (CNode n'étant pas important ici). m_Root est initialisé a NULL par défaut et le compteur à 1. Maitenant dans la fonction ReadScene :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bool CSceneManager::ReadScene(std::string const &Filename)
    {
         //...
     
         // Load the scene :
         CNodePtr NodeTmp = Loader->LoadScene(Filename);  // compteur à 1!!
         bool b = ReadScene(NodeTmp);                     // compteur à 2
         return b;                                        // compteur à 0
    }
    Une petite explication s'impose, Loader est une instance de classe permettant de charger des scènes, la fonction LoadScene renvoie un CNodePtr correspondant à la scène chargée. Et enfin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    bool CSceneManager::ReadScene(CNodePtr Root)
    {
         //...
         m_Root = Root;   //compteur à 3
         return true;
    }
    Résultat l'objet est détruit... et je bloc dessus depuis un bon moment déjà alors que ça à l'air idiot (mais bon c'est toujours comme ça)
    Si vous avez besoin de plus de code (CSmartPointer, fonctions...) n'hésitez pas à demander...

    Merci d'avance et bonne fin de journée

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Plutôt que de perdre du temps à (mal) refaire la roue pourquoi tu n'utilises pas boost ?

    MAT.

  3. #3
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Plutôt que de perdre du temps à (mal) refaire la roue
    Cette argument est souvent cité, personnellement je fais partie de ceux qui aiment "refaire la roue", la question n'est pas de la refaire (bien ou mal), je continuerai d'ailleurs d'utiliser boost, mais le but est d'apprendre... ce n'est donc pas une perte de temps à mon avis (mais bon après c'est personnel).

    J'utilise ma classe dans ce projet afin de la tester tout simplement...

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Ok, mettons...

    Il faudrait sans doute en effet le code de CSmartPointer pour savoir exactement ce qui se passe.

    MAT.

  5. #5
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Voila un code plus complet sur ma classe mais je ne vois toujours pas d'erreur
    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
    template <class T>
    class CSmartPointer
    {
    public:
     
    	// Constructor :
    	CSmartPointer(T *Pointer = NULL);
    	CSmartPointer(CSmartPointer<T> const &SmartPointer);
     
    	// Destructor :
    	~CSmartPointer();
     
    	// Operator :
    	CSmartPointer<T> & operator = (CSmartPointer<T> const &SmartPointer);
    	//...
     
    	//....
     
    private:
     
    	T		*m_Pointer;			// Pointer on the object
    	int		*m_Counter;			// Counter on the object pointed
    };
    Et le .inl mais toujours rien de compliqué :
    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
    //Constructor (1param) :
    template <class T>
    inline CSmartPointer<T>::CSmartPointer(T *Pointer)
    {
    	// Initialisation :
    	m_Pointer = Pointer;
    	m_Counter = new int(1);
    }
     
    //Copy constructor :
    template <class T>
    inline CSmartPointer<T>::CSmartPointer(CSmartPointer<T> const &SmartPointer)
    {
    	// Copy :
    	m_Pointer = SmartPointer.m_Pointer;
    	m_Counter = SmartPointer.m_Counter;
     
    	// Incrementation :
    	++(*m_Counter);
    }
     
    //Destructor :
    template <class T>
    inline CSmartPointer<T>::~CSmartPointer()
    {
    	// Decrementation :
    	if( --(*m_Counter) == 0 )
    	{
    		delete m_Pointer;
    		delete m_Counter;
    	}
    }
     
    //Operator = :
    template <class T>
    inline CSmartPointer<T> & CSmartPointer<T>::operator = (CSmartPointer<T> const &SmartPointer)
    {
    	Assert( (this != &SmartPointer) );
     
    	// Decrementation :
    	if( --(*m_Counter) == 0 )
    	{
    		delete m_Pointer;
    		delete m_Counter;
    	}
     
    	// Copy :
    	m_Pointer = SmartPointer.m_Pointer;
    	m_Counter = SmartPointer.m_Counter;
     
    	// Incrementation :
    	++(*m_Counter);
     
    	return *this;
    }
    Je passe ici les détails sur les opérateurs de casts, prédicat etc...

    Mais ce qui me surprend le plus c'est à ce niveau la :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CNodePtr NodeTmp = Loader->LoadScene(Filename);  // compteur à 1!!
    Le compteur devrait être à deux (je suppose) mais je ne trouve pas l'erreur

  6. #6
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    Tu peux montrer un main et ton Loader pour qu'on voit un cas typique d'utilisation?


    Note:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	// Copy :
    	m_Pointer = SmartPointer.m_Pointer;
    	m_Counter = SmartPointer.m_Counter;
    Ici j'espère que t'es conscient que tu ne fais pas une copy véritable mais tu fais seulement pointer tes pointeurs sur les mêmes addresses que SmartPointer ?

    (Aussi, ourquoi utiliser un pointeur sur un entier au lieu de tout simplement utiliser un entier? Je vois pas l'intérêt dans ton cas.)

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par babar63 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template <class T>
    class CSmartPointer
    {
    public:
     
    	// Constructor :
    	CSmartPointer(T *Pointer = NULL);
    C'est volontairement que tu déclare une conversion implicite de T* vers CSmartPointer?

    Si ce n'est pas le cas, ajoute le mot-clef "explicite".

    Citation Envoyé par babar63 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template <class T>
    inline CSmartPointer<T>::CSmartPointer(T *Pointer)
    {
    	// Initialisation :
    	m_Pointer = Pointer;
    	m_Counter = new int(1);
    }
    Il est idiomatique d'utiliser la liste d'initialisation, même quand ça ne change pas la signification du code, comme ici (les membres ont tous un type de base).

    Citation Envoyé par babar63 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //Copy constructor :
    template <class T>
    inline CSmartPointer<T>::CSmartPointer(CSmartPointer<T> const &SmartPointer)
    {
    	// Copy :
    	m_Pointer = SmartPointer.m_Pointer;
    	m_Counter = SmartPointer.m_Counter;
    Idem.

    Citation Envoyé par babar63 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	// Incrementation :
    	++(*m_Counter);
    }
     
    //Operator = :
    template <class T>
    inline CSmartPointer<T> & CSmartPointer<T>::operator = (CSmartPointer<T> const &SmartPointer)
    {
    	Assert( (this != &SmartPointer) );
    Pourquoi assert? Tu veux interdire l'auto-affectation?

    Citation Envoyé par babar63 Voir le message
    Mais ce qui me surprend le plus c'est à ce niveau la :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CNodePtr NodeTmp = Loader->LoadScene(Filename);  // compteur à 1!!
    Le compteur devrait être à deux (je suppose) mais je ne trouve pas l'erreur
    Des détails sur LoadScene?

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

Discussions similaires

  1. Flash Disque non fonctionnel
    Par stanley dans le forum Composants
    Réponses: 2
    Dernier message: 18/07/2006, 12h18
  2. Code non fonctionnel sous IE
    Par Nip dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 07/06/2006, 14h59
  3. timage non fonctionnel !!
    Par micky13 dans le forum Delphi
    Réponses: 5
    Dernier message: 13/05/2006, 07h21
  4. Update non fonctionnel
    Par kissmytoe dans le forum Access
    Réponses: 7
    Dernier message: 07/03/2006, 18h37
  5. [REPORTS] Order BY non fonctionnel
    Par sdiack dans le forum Reports
    Réponses: 2
    Dernier message: 10/02/2006, 18h10

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