begin process at 2012 05 27 19:20:45
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Astuces

 > SMART POINTEUR À COMPTEUR DE RÉFÉRENCE

SMART POINTEUR À COMPTEUR DE RÉFÉRENCE


 Information sur la source

Note :
Aucune note
Catégorie :Astuces Classé sous :pointeur, intelligent, template, compteur, reference Niveau :Débutant Date de création :08/12/2009 Date de mise à jour :08/12/2009 11:49:03 Vu :2 633

Auteur : nirgal76

Ecrire un message privé
Commentaire sur cette source (10)
Ajouter un commentaire et/ou une note

 Description

Encore un pointeur intelligent, à compteur de référence, qui se comporte à l'utilisation comme un pointeur traditionnel. Attention, il n'est pas threadsafe.
Il a été fait en Builder C++ 2007.

Source

  • //******************************************************************************
  • //! @file TSmartPtr.h
  • //! @brief Gestion des pointeurs intelligents
  • //******************************************************************************
  • //******************************************************************************
  • // Version : 01
  • // Date : 11/2008
  • // Auteurs : Nirgal76 / Totoche76
  • // Description :
  • // - Création de la classe
  • //******************************************************************************
  • #ifndef _TSmartPtrH
  • #define _TSmartPtrH
  • //******************************************************************************
  • // MACROS
  • //******************************************************************************
  • #define SAFE_DELETE(p) { if (NULL!=p) { delete p; p=NULL; } }
  • #define SAFE_DELETE_ARRAY(p) { if (NULL!=p) { delete[] p; p=NULL; } }
  • //******************************************************************************
  • // CONSTANTES
  • //******************************************************************************
  • const bool C_PTR_ARRAY = true; //!< Pointeur de base array
  • const bool C_PTR_SINGLE = false; //!< Pointeur de base simple
  • //******************************************************************************
  • //! @class TSmartPtr
  • //! @author Nirgal76
  • //! @author Totoche76
  • //! @date 11/2007
  • //! @brief Classe de gestion de pointeurs intelligents
  • //******************************************************************************
  • template <typename T, bool Array = C_PTR_SINGLE>
  • class TSmartPtr
  • {
  • //=====================================
  • // PUBLIC
  • //=====================================
  • public :
  • //------------------
  • // CYCLE DE VIE
  • //------------------
  • // Constructeurs
  • TSmartPtr();
  • // Constructeurs par copie
  • TSmartPtr(const TSmartPtr& rSmartPtr);
  • // Constructeurs à partir d'un pointeur c++
  • TSmartPtr(T* pPointer);
  • // destructeur
  • ~TSmartPtr();
  • //------------------
  • // OPERATEURS
  • //------------------
  • // Opérations sur le pointeur
  • TSmartPtr& operator=(const TSmartPtr& rSmartPtr);
  • TSmartPtr& operator=(T* pPointer);
  • T& operator*();
  • T* operator->();
  • const T& operator*() const;
  • const T* operator->() const;
  • bool operator==(const TSmartPtr& rSmartPtr) const;
  • bool operator!=(const TSmartPtr& rSmartPtr) const;
  • operator T*(void) const;
  • //=====================================
  • // PRIVATE
  • //=====================================
  • private:
  • //------------------
  • // DONNEES
  • //------------------
  • int* mpRefCounter; //!< Nombre de référence sur le pointeur
  • T* mpPointer; //!< Pointeur de base
  • //------------------
  • // METHODES
  • //------------------
  • // Destruteur (par comptage de référence)
  • void Release();
  • }; // fin de TSmartPtr
  • //******************************************************************************
  • //! @brief Constructeur
  • //!
  • //! @param Aucun
  • //!
  • //! @return Aucun
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline TSmartPtr<T, Array>::TSmartPtr()
  • {
  • mpRefCounter=NULL;
  • mpPointer=NULL;
  • }// fin du constructeur
  • //******************************************************************************
  • //! @brief Constructeur par copie
  • //!
  • //! @param rSmartPtr : pointeur intelligent à copier
  • //!
  • //! @return Aucun
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline TSmartPtr<T, Array>::TSmartPtr(const TSmartPtr<T, Array>& rSmartPtr)
  • {
  • mpPointer = rSmartPtr.mpPointer;
  • mpRefCounter = rSmartPtr.mpRefCounter;
  • if (NULL!=mpRefCounter)
  • ++(*mpRefCounter);
  • }// fin du constructeur par copie d'un pointeur intelligent
  • //******************************************************************************
  • //! @brief Constructeur par copie d'un pointeur de base
  • //!
  • //! @param pPointer : pointeur de base à copier
  • //!
  • //! @return Aucun
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline TSmartPtr<T, Array>::TSmartPtr(T* pPointer)
  • {
  • mpPointer=pPointer;
  • if (NULL==mpPointer)
  • mpRefCounter = NULL;
  • else
  • mpRefCounter = new int(1);
  • }// fin du constructeur
  • //******************************************************************************
  • //! @brief Destructeur
  • //!
  • //! @param Aucun
  • //!
  • //! @return Aucun
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline TSmartPtr<T, Array>::~TSmartPtr()
  • {
  • Release();
  • }// fin du destructeur
  • //******************************************************************************
  • //! @brief Opérateur d'affectation (=)
  • //!
  • //! @param rSmartPtr : pointeur intelligent source
  • //!
  • //! @return Le pointeur
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline TSmartPtr<T, Array>& TSmartPtr<T, Array>::operator=(const TSmartPtr<T, Array>& rSmartPtr)
  • {
  • Release();
  • mpPointer = rSmartPtr.mpPointer;
  • mpRefCounter = rSmartPtr.mpRefCounter;
  • if (NULL!=mpRefCounter)
  • ++(*mpRefCounter);
  • return *this;
  • }// fin de l'opérateur d'affectation
  • //******************************************************************************
  • //! @brief Opérateur d'affectation (=)
  • //!
  • //! @param pPointer : Pointeur de base
  • //!
  • //! @return Le pointeur
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline TSmartPtr<T, Array>& TSmartPtr<T, Array>::operator=(T* pPointer)
  • {
  • Release();
  • mpPointer = pPointer;
  • if (NULL==mpPointer)
  • mpRefCounter = NULL;
  • else
  • mpRefCounter = new int(1);
  • return *this;
  • }// fin de l'opérateur d'affectation
  • //******************************************************************************
  • //! @brief Opérateur d'égalité (==)
  • //!
  • //! @param rSmartPtr : pointeur intelligent à comparer
  • //!
  • //! @return true si les pointeurs sont égaux
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline bool TSmartPtr<T, Array>::operator==(const TSmartPtr<T, Array>& rSmartPtr) const
  • {
  • return mpPointer == rSmartPtr.mpPointer;
  • }// fin de l'opérateur d'égalité
  • //******************************************************************************
  • //! @brief Opérateur de non égalité (!=)
  • //!
  • //! @param rSmartPtr : pointeur intelligent à comparer
  • //!
  • //! @return true si les pointeurs sont différents
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline bool TSmartPtr<T, Array>::operator!=(const TSmartPtr<T, Array>& rSmartPtr) const
  • {
  • return mpPointer != rSmartPtr.mpPointer;
  • }// fin de l'opérateur de non égalité
  • //******************************************************************************
  • //! @brief Renvoi la valeur du pointeur (opérateur *)
  • //!
  • //! @param Aucun
  • //!
  • //! @return Valeur du pointeur
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline T& TSmartPtr<T, Array>::operator*()
  • {
  • return *mpPointer;
  • }// fin de l'opérateur de valeur
  • //******************************************************************************
  • //! @brief Renvoi la référence du pointeur (opérateur ->)
  • //!
  • //! @param Aucun
  • //!
  • //! @return Référence du pointeur
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline T* TSmartPtr<T, Array>::operator->()
  • {
  • return mpPointer;
  • }// fin de l'opérateur de référence
  • //******************************************************************************
  • //! @brief Renvoi la référence du pointeur (opérateur *) en const
  • //!
  • //! @param Aucun
  • //!
  • //! @return Référence const du pointeur
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline const T& TSmartPtr<T, Array>::operator*() const
  • {
  • return *mpPointer;
  • }// fin de l'opérateur de valeur
  • //******************************************************************************
  • //! @brief Renvoi la référence du pointeur (opérateur ->) en const
  • //!
  • //! @param Aucun
  • //!
  • //! @return Référence const du pointeur
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline const T* TSmartPtr<T, Array>::operator->() const
  • {
  • return mpPointer;
  • }// fin de l'opérateur de référence
  • //******************************************************************************
  • //! @brief Casting sur le pointeur intelligent
  • //!
  • //! @param Aucun
  • //!
  • //! @return Pointeur de base
  • //******************************************************************************
  • template<typename T, bool Array>
  • inline TSmartPtr<T, Array>::operator T*(void) const
  • {
  • return mpPointer;
  • }// fin de l'opérateur de casting
  • //******************************************************************************
  • //! @brief Décrémente le compteur de référence et supprime le pointeur si = à 0
  • //!
  • //! @param Aucun
  • //!
  • //! @return Aucun
  • //******************************************************************************
  • template <typename T, bool Array>
  • inline void TSmartPtr<T, Array>::Release()
  • {
  • if (NULL!=mpRefCounter)
  • {
  • (*mpRefCounter)--;
  • if (*mpRefCounter <= 0)
  • {// compteur = 0 => destruction du pointeur
  • if (Array)
  • {// tableau de pointeur
  • SAFE_DELETE(mpRefCounter);
  • SAFE_DELETE_ARRAY(mpPointer);
  • }
  • else
  • {// pointeur
  • SAFE_DELETE(mpRefCounter);
  • SAFE_DELETE(mpPointer);
  • }
  • }// fin de compteur = 0
  • }
  • }// fin de Release
  • #endif
//******************************************************************************
//! @file   TSmartPtr.h
//! @brief  Gestion des pointeurs intelligents
//******************************************************************************

//******************************************************************************
// Version     : 01
// Date        : 11/2008
// Auteurs     : Nirgal76 / Totoche76
// Description :
// - Création de la classe
//******************************************************************************
#ifndef _TSmartPtrH
#define _TSmartPtrH

//******************************************************************************
// MACROS
//******************************************************************************
#define SAFE_DELETE(p)       { if (NULL!=p) { delete p; p=NULL; } }
#define SAFE_DELETE_ARRAY(p) { if (NULL!=p) { delete[] p; p=NULL; } }

//******************************************************************************
// CONSTANTES
//******************************************************************************
const bool C_PTR_ARRAY = true;   //!< Pointeur de base array
const bool C_PTR_SINGLE = false; //!< Pointeur de base simple

//******************************************************************************
//! @class  TSmartPtr
//! @author Nirgal76
//! @author Totoche76
//! @date   11/2007
//! @brief  Classe de gestion de pointeurs intelligents
//******************************************************************************
template <typename T, bool Array = C_PTR_SINGLE>
class TSmartPtr
{
//=====================================
// PUBLIC
//=====================================
public :
//------------------
// CYCLE DE VIE
//------------------
  // Constructeurs
  TSmartPtr();
  // Constructeurs par copie
  TSmartPtr(const TSmartPtr& rSmartPtr);
  // Constructeurs à partir d'un pointeur c++
  TSmartPtr(T* pPointer);
  // destructeur
  ~TSmartPtr();

//------------------
// OPERATEURS
//------------------
  // Opérations sur le pointeur
  TSmartPtr& operator=(const TSmartPtr& rSmartPtr);
  TSmartPtr& operator=(T* pPointer);
  T& operator*();
  T* operator->();
  const T& operator*() const;
  const T* operator->() const;
  bool operator==(const TSmartPtr& rSmartPtr) const;
  bool operator!=(const TSmartPtr& rSmartPtr) const;
  operator T*(void) const;

//=====================================
// PRIVATE
//=====================================
private:
//------------------
// DONNEES
//------------------
  int* mpRefCounter; //!< Nombre de référence sur le pointeur
  T* mpPointer;      //!< Pointeur de base

  //------------------
// METHODES
//------------------
  // Destruteur (par comptage de référence)
  void Release();
}; // fin de TSmartPtr

//******************************************************************************
//! @brief  Constructeur
//!
//! @param  Aucun
//!
//! @return Aucun
//******************************************************************************
template <typename T, bool Array>
inline TSmartPtr<T, Array>::TSmartPtr()
{
  mpRefCounter=NULL;
  mpPointer=NULL;
}// fin du constructeur

//******************************************************************************
//! @brief  Constructeur par copie
//!
//! @param  rSmartPtr : pointeur intelligent à copier
//!
//! @return Aucun
//******************************************************************************
template <typename T, bool Array>
inline TSmartPtr<T, Array>::TSmartPtr(const TSmartPtr<T, Array>& rSmartPtr)
{
  mpPointer = rSmartPtr.mpPointer;
  mpRefCounter = rSmartPtr.mpRefCounter;
  if (NULL!=mpRefCounter)
    ++(*mpRefCounter);
}// fin du constructeur par copie d'un pointeur intelligent

//******************************************************************************
//! @brief  Constructeur par copie d'un pointeur de base
//!
//! @param  pPointer : pointeur de base à copier
//!
//! @return Aucun
//******************************************************************************
template <typename T, bool Array>
inline TSmartPtr<T, Array>::TSmartPtr(T* pPointer)
{
  mpPointer=pPointer;
  if (NULL==mpPointer)
    mpRefCounter = NULL;
  else
    mpRefCounter = new int(1);
}// fin du constructeur

//******************************************************************************
//! @brief  Destructeur
//!
//! @param  Aucun
//!
//! @return Aucun
//******************************************************************************
template <typename T, bool Array>
inline TSmartPtr<T, Array>::~TSmartPtr()
{
  Release();
}// fin du destructeur

//******************************************************************************
//! @brief  Opérateur d'affectation (=)
//!
//! @param  rSmartPtr : pointeur intelligent source
//!
//! @return Le pointeur
//******************************************************************************
template <typename T, bool Array>
inline TSmartPtr<T, Array>& TSmartPtr<T, Array>::operator=(const TSmartPtr<T, Array>& rSmartPtr)
{
  Release();

  mpPointer = rSmartPtr.mpPointer;
  mpRefCounter = rSmartPtr.mpRefCounter;
  if (NULL!=mpRefCounter)
    ++(*mpRefCounter);

  return *this;
}// fin de l'opérateur d'affectation

//******************************************************************************
//! @brief  Opérateur d'affectation (=)
//!
//! @param  pPointer : Pointeur de base
//!
//! @return Le pointeur
//******************************************************************************
template <typename T, bool Array>
inline TSmartPtr<T, Array>& TSmartPtr<T, Array>::operator=(T* pPointer)
{
  Release();

  mpPointer = pPointer;
  if (NULL==mpPointer)
    mpRefCounter = NULL;
  else
    mpRefCounter = new int(1);

  return *this;
}// fin de l'opérateur d'affectation

//******************************************************************************
//! @brief  Opérateur d'égalité (==)
//!
//! @param  rSmartPtr : pointeur intelligent à comparer
//!
//! @return true si les pointeurs sont égaux
//******************************************************************************
template <typename T, bool Array>
inline bool TSmartPtr<T, Array>::operator==(const TSmartPtr<T, Array>& rSmartPtr) const
{
  return mpPointer == rSmartPtr.mpPointer;
}// fin de l'opérateur d'égalité

//******************************************************************************
//! @brief  Opérateur de non égalité (!=)
//!
//! @param  rSmartPtr : pointeur intelligent à comparer
//!
//! @return true si les pointeurs sont différents
//******************************************************************************
template <typename T, bool Array>
inline bool TSmartPtr<T, Array>::operator!=(const TSmartPtr<T, Array>& rSmartPtr) const
{
  return mpPointer != rSmartPtr.mpPointer;
}// fin de l'opérateur de non égalité

//******************************************************************************
//! @brief  Renvoi la valeur du pointeur (opérateur *)
//!
//! @param  Aucun
//!
//! @return Valeur du pointeur
//******************************************************************************
template <typename T, bool Array>
inline T& TSmartPtr<T, Array>::operator*()
{
  return *mpPointer;
}// fin de l'opérateur de valeur

//******************************************************************************
//! @brief  Renvoi la référence du pointeur (opérateur ->)
//!
//! @param  Aucun
//!
//! @return Référence du pointeur
//******************************************************************************
template <typename T, bool Array>
inline T* TSmartPtr<T, Array>::operator->()
{
  return mpPointer;
}// fin de l'opérateur de référence

//******************************************************************************
//! @brief  Renvoi la référence du pointeur (opérateur *) en const
//!
//! @param  Aucun
//!
//! @return Référence const du pointeur
//******************************************************************************
template <typename T, bool Array>
inline const T& TSmartPtr<T, Array>::operator*() const
{
  return *mpPointer;
}// fin de l'opérateur de valeur

//******************************************************************************
//! @brief  Renvoi la référence du pointeur (opérateur ->) en const
//!
//! @param  Aucun
//!
//! @return Référence const du pointeur
//******************************************************************************
template <typename T, bool Array>
inline const T* TSmartPtr<T, Array>::operator->() const
{
  return mpPointer;
}// fin de l'opérateur de référence

//******************************************************************************
//! @brief  Casting sur le pointeur intelligent
//!
//! @param  Aucun
//!
//! @return Pointeur de base
//******************************************************************************
template<typename T, bool Array>
inline TSmartPtr<T, Array>::operator T*(void) const
{
  return mpPointer;
}// fin de l'opérateur de casting

//******************************************************************************
//! @brief  Décrémente le compteur de référence et supprime le pointeur si = à 0
//!
//! @param  Aucun
//!
//! @return Aucun
//******************************************************************************
template <typename T, bool Array>
inline void TSmartPtr<T, Array>::Release()
{
  if (NULL!=mpRefCounter)
  {
    (*mpRefCounter)--;
    if (*mpRefCounter <= 0)
    {// compteur = 0 => destruction du pointeur
      if (Array)
      {// tableau de pointeur
        SAFE_DELETE(mpRefCounter);
        SAFE_DELETE_ARRAY(mpPointer);
      }
      else
      {// pointeur
        SAFE_DELETE(mpRefCounter);
        SAFE_DELETE(mpPointer);
      }
    }// fin de compteur = 0
  }
}// fin de Release

#endif

 Conclusion

Reste à le déclarer. Par exemple, pour déclarer un pointeur sur une classe TMaClasse :
  TSmartPtr<TMaClasse> mpMaClasse;

mpMaClasse=new TMaClasse;  // Instanciation de TMaClasse
mpMaClasse->Initialiser(); // Fonction membre de TMaClasse
...


Et ensuite, l'utiliser comme un pointeur traditionnel. sauf qu'il n'y a pas à le deleter bien entendu.
Si l'on veut vraiment le supprimer explicitement, lui affecter NULL.


 Historique

08 décembre 2009 11:49:03 :
Mise à jour des auteurs du code

 Sources de la même categorie

Source avec Zip Source avec une capture EVAL EXPRESSION COMPLEXE EN 15 LIGNES DE CODE par yann_lo_san
Source avec Zip SCHEDULER RR FIFO par yvesB87
Source avec Zip ALGORITHMES RÉCURSIFS VS ALGORITHMES ITÉRATIFS par yvesB87
Source avec Zip Source avec une capture C++ FORMAT D'IMAGE AVEC QT par pop70
Source avec une capture EXEMPLE DE POINTEURS DE FONCTION par pop70

 Sources en rapport avec celle ci

UTILISATION DES TYPELIST EN C++ par wyden
Source avec Zip POINTEUR INTELLIGENT par DrMckey
Source avec Zip TEMPLATES C/C++ POUR VS 2010 par BruNews
Source avec une capture EXEMPLE DE POINTEURS DE FONCTION par pop70
POINTEUR INTELLIGENT par snpier wolf

Commentaires et avis

Commentaire de CptPingu le 09/12/2009 11:16:18 administrateur CS

Et encore un smart pointer défecteux !
Il existe des std::smart_ptr, autant les utiliser !

#define SAFE_DELETE(p) { if (NULL!=p) { delete p; p=NULL; } }
#define SAFE_DELETE_ARRAY(p) { if (NULL!=p) { delete[] p; p=NULL; } }

Ca c'est con, parce que "delete NULL;" est valide et ne fait rien. "if (NULL!=p) { delete p; p=NULL; }" peut être remplacé par: "delete p; p=NULL;"

Ensuite, ton code leak !!! Il ne détruit pas correctement tout ce qu'il faut.

Exemple:
#include "smart.hh"
#include <iostream>

int main()
{
  TSmartPtr<int> mpMaClasse;
  TSmartPtr<int> mpMaClasse2;

  int* a = new int;

  mpMaClasse = a;
  *mpMaClasse = 45;

  std::cout << *mpMaClasse << std::endl;

  mpMaClasse2 = a;
  *mpMaClasse2 = 18;

  std::cout << *mpMaClasse << std::endl;
  std::cout << *mpMaClasse2 << std::endl;

  return 0;
}

Ici, a est libéré deux fois. Ca ne se voit pas forcément, mais en passant un coup de valgrind:
valgrind ./a.out
==4527== Memcheck, a memory error detector
==4527== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==4527== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==4527== Command: ./a.out
==4527==
45
18
18
==4527== Invalid free() / delete / delete[]
==4527==    at 0x402454D: operator delete(void*) (vg_replace_malloc.c:346)
==4527==    by 0x8048A1A: TSmartPtr<int, false>::Release() (in /tmp/a.out)
==4527==    by 0x804895E: TSmartPtr<int, false>::~TSmartPtr() (in /tmp/a.out)
==4527==    by 0x80488B1: main (in /tmp/a.out)
==4527==  Address 0x42bb028 is 0 bytes inside a block of size 4 free'd
==4527==    at 0x402454D: operator delete(void*) (vg_replace_malloc.c:346)
==4527==    by 0x8048A1A: TSmartPtr<int, false>::Release() (in /tmp/a.out)
==4527==    by 0x804895E: TSmartPtr<int, false>::~TSmartPtr() (in /tmp/a.out)
==4527==    by 0x804888D: main (in /tmp/a.out)
==4527==
==4527==
==4527== HEAP SUMMARY:
==4527==     in use at exit: 0 bytes in 0 blocks
==4527==   total heap usage: 3 allocs, 4 frees, 12 bytes allocated
==4527==
==4527== All heap blocks were freed -- no leaks are possible
==4527==
==4527== For counts of detected and suppressed errors, rerun with: -v
==4527== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 19 from 8)


En effet, tu ne partages pas de refCounter entre tes classes. Donc ca ne sert à rien.
La seule solution viable, est d'avoir un flyweight. C'est-à-dire une collection statique partagée par toutes les instances de ta classe smart, et dans lequel tu partages tous ce qui est référencé. Un compteur un tenu pour chaque élément. Ainsi, un élément ne sera détruit que si plus personne ne pointe dessus, quelque soit l'endroit dans le code, et même avec deux instances différentes de ta classe smart.

Commentaire de BloodReapR le 16/12/2009 15:53:40

Pour le  "if (NULL!=p) { delete p; p=NULL; }" je crois qu'il devrait rester comme ça. Parce qu'un appel direct à delete sans en avoir besoin prend plus de ressource qu'un simple if. C'est juste une petite question de performance.

Commentaire de CptPingu le 16/12/2009 16:02:33 administrateur CS

C'est faux. Je te rappelle que delete et new sont des opérateurs (qui peuvent d'ailleurs être redéfinis). Ce sont donc des fonctions. Le cas if (p != NULL) est testé *dans* le delete. Inutile de le remettre et non il n'y a pas de différence de performance.
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.8

A noté que 0 devrait être employé plutôt que NULL.
http://cpp.developpez.com/faq/bcb/?page=langage#langagenull

Commentaire de nirgal76 le 16/12/2009 16:43:51

>Il existe des std::smart_ptr, autant les utiliser !
ben le but est de s'amuser à en refaire un, c'est quand comme ça que l'on apprends le mieux.

pour l'utilisation de NULL:  selon le lien http://cpp.developpez.com/faq/bcb/?page=langage#langagenull
aucun soucis à l'utiliser puisque c'est en Builder C++.

le if (NULL!=p) :
Oui, delete fait le meme test donc aucun gain en performance si le pointeur est à NULL, et baisse en performance même s'il n'est pas à NULL car le test sera fait 2 fois. La seule utilité serait si delete était redéfini et sans le test...mais ça serait une erreur.
à l'origine, ce SAFE_DELETE, c'est une macro que j'avais repris du sdk directx sans vraiment m'en préoccuper. j'aurais du ;)

En bref, merci pour vos commentaires, le but était de me faire corriger mon code ;). Cela me sera très utile (même si je ne l'utilise jamais dans le cas de l'exemple qui provoque une fuite).

Commentaire de CptPingu le 16/12/2009 16:53:23 administrateur CS

> c'est en Builder C++
C'est plutôt une recommendation générale sur le C++ qui n'est pas restreinte à Builder C++. (Faite par le créateur du C++ lui même). Ce ne provoquera pas d'erreur, c'est une juste une question de style.

> ben le but est de s'amuser à en refaire un, c'est quand comme ça que l'on apprends le mieux.
Absolument, c'est légitime. Le code est propre et bien commenté, mais il faudrait tout de même expliquer dans la descriptions que c'est un code à but didactique, et que la STL est à privilégier.

> même si je ne l'utilise jamais dans le cas de l'exemple qui provoque une fuite
Enfin, le cas que je t'ai présenté reste un bug, qu'il serait sympa de corriger, ou tout du moins d'empêcher :).
Soit dit en passant, ça ne provoque pas vraiment une fuite, mais une tentative d'accès mémoire invalide (libération multiples du même espace mémoire).

Commentaire de nirgal76 le 16/12/2009 16:58:37

Oui je vais remédier à ça. plutot en l'empêchant d'ailleurs comme c'est une fonctionnalité que je ne vais pas utiliser.

pour NULL, c'est vrai mais j'ai pris l'habitude avec l'aide et les exemples de builder à toujours voir des NULL et du coup, j'ai pris le mauvais pli :/

Merci en tout cas

Commentaire de BloodReapR le 16/12/2009 17:41:22

Oui NULL est un macro de 0, je l'utilize seulement dans le cas des pointeurs pour les différentier des entiers habituels. Mais apropos de la verification du pointeur avec 0 avant l'appel de delete, je disais que c'était une question de performance parce que justement t'évite te faire un appel à la fonction delete par un if. La différence je sais n'est pas grande mais moi dans ma tête je me dis vaut mieux faire un if qu'un appel de fonction.

Commentaire de CptPingu le 16/12/2009 17:45:17 administrateur CS

> La différence je sais n'est pas grande mais moi dans ma tête je me dis vaut mieux faire un if qu'un appel de fonction.
Bof.
1) L'inlining est très efficace (transformation d'une fonction en uniquement son corps, donc pas d'appel).
2) De plus, dans le cas ou le pointeur est différent de null, ce qui est quand même très souvent le cas, tu fais deux fois la vérification.

Commentaire de BloodReapR le 16/12/2009 19:05:53

Puisque je construis ma propre classe de smart_ptr (pour des raisons de simplicité et apprentissage) j'ai remarqué que ta fonction release ne fait pas le boulot qu'elle est censée faire (selon le STL). Release en fait devrait avoir comme valeur de retour le pointeur de la memoire alloqué et rendre le pointeur membre "NULL". Ex:


inline T * TSmartPtr<T, Array>::Release()
{
    T *pPtr = mpPointer;
    mpPointer = NULL;  // ou '0' si vous préferez
    return pPtr;
}

Commentaire de BloodReapR le 16/12/2009 19:16:58

>> 1) L'inlining est très efficace (transformation d'une fonction en >>uniquement son corps, donc pas d'appel).

Oui je sais apropos du inline mais d'après ce que je me souviens, pour Windows ou Linux (ou tout autre OS) c'est un appel de fonction spécifique (du OS) pour l'allocation de mémoire heap. Ce qui rend la fonction non-inlinable. Mais comme j'ai dit c'est d'après ce que je me souviens.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

les template [ par FlyFucker ] Bonjour,peut on se servir d'un struct en temps que type d'un template !car avec le template que j'ai fait, au moment de l'integration dans mon program convertir pointeur int* en reference int& ??? je fais quoi ? [ par equimose ] j'ai une fonction qui prend comme parametre une CMyLigne &amp; ABet j'ai besoin d'envoyer a cette fonction un pointeur sur une CMyLigne * pLigne !c'es Unresolved external symbol [ par neodelphi ] Bonsoir, c'est encore moi et mes probl&#232;mes de c++ !Je vais essayer de faire cour:J'ai une&nbsp;classe template dans un fichier .hpp (d&#233;clara [C] Pointeur int comme paramètre dans une function qui ne marche pas [ par nitrique ] Bonjour &#224; tous,J'ai retourn&#233; les pointeurs dans tous les sens mais rien n'y fait.J'aimerais modifier la valeur d'une variable int &#224; l'i Utilisation d'un pointeur de fonction membre [ par cyrcocq ] Bonjour,J'ai d&#233;j&#224; discut&#233; de &#231;a ailleurs, on m'a conseill&#233; d'autres m&#233;thodes, mais imaginons une classe contenant un ens reference nulle [ par Binabik ] salut tout le monde,est ce que quelqu'un sait comment retourner une reference nulle en c++?merci ^^.vive les grottes Pointeur de Fonction [ par Ombitious_Developper ] Salut : Mon probl&#233;me est le suivant :Etant donn&#233; une classe class TMyClass{&nbsp;// donn&#233;es membres&nbsp;public :&nbsp;void&nbsp;&nbsp [C] [Dev-cpp] undefinied reference to URLDownloadToFile [ par shadow1779 ] Bonjour,voila j'ai encore un probleme d'undefinied reference : la c'est un undefinied reference to URLDownloadToFile, avec Dev-cpp en programmation C, [C#] récupérer la position du pointeur [ par Napalm51 ] Bonjour, en fait j'essaye de developper un programme qui ouvre un fichier texte, l'affiche dans une RichTextBox, et qd un utilisateur surligne une par Pointeurs de pointeurs [ par miximog ] Bonjour a tous enfin bonsoir ;) Enfa&#238;te j'ai lu 2 tuto sur les pointeurs donc je commence a bien comprendre la notion de pointeurs, mais il y a


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

Photothèque

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,624 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales