Soyez le premier à donner votre avis sur cette source.
Snippet vu 6 486 fois - Téléchargée 21 fois
//****************************************************************************** //! @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
16 déc. 2009 à 19:16
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.
16 déc. 2009 à 19:05
inline T * TSmartPtr<T, Array>::Release()
{
T *pPtr = mpPointer;
mpPointer = NULL; // ou '0' si vous préferez
return pPtr;
}
16 déc. 2009 à 17:45
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.
16 déc. 2009 à 17:41
16 déc. 2009 à 16:58
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
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.