Pointeur intelligent

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 216 fois - Téléchargée 20 fois

Contenu du snippet

Bonjour à tous,
voici mon pointeur intelligent,
cette une class qui sutilise comme un pointeur normale (ou presque) mais elle gère toute seule la suppression des allocations de mêmoire.
je l'ai consue surtout pour comprendre les templates mais je vous le pose pour voir si vous voyez
des bugs car il saurat implenté dans un projet plus gros.

Source / Exemple :


#ifndef _IPointer_H
#define _IPointer_H
#include <map>

       
template<class T>
class IPointer
{
    public :
        //destructeur
        ~IPointer()throw();
       //constructeur par defaut
        IPointer() : m_Ptrs((T*)0)
        {}
        //constructer par pointeur
        IPointer(T* Ptr);
        //constructeur par copie
        IPointer(const IPointer& Ptr);
        //operateur de déferencement 
        T&   operator * ()const ;
        T* operator ->()const ;
        //operateur de positionnement
        T operator -- (int) ;
        T operator ++ (int) ;
        //operateur de renvoit
        operator T*() const ;
        //operateur =
        const IPointer& operator =(const IPointer& Ptr) ;
        const IPointer& operator = (T* Ptr) ;
        //echange d'addresse
        void AddressSwap( IPointer& Ptr) ;
        //echange de valeur
        void ValueSwap( IPointer& Ptr) ;
        //comparéson de valeur
        bool ValueCmp(const IPointer& Ptr) ;
 
    private:
    // pointeur
    T* m_Ptrs;
    //map de sauvegarde addresse
    typedef std::map< IPointer*,T*>mapBlock;
    mapBlock Block;
};
//////////////////////////////////////
//destructeur
// 
// suprime la savegarde pointeur
//////////////////////////////////////
template<class T>inline IPointer<T>::~IPointer()throw()
{
delete Block[this];
}

//////////////////////////////////////////
//constructeur par pointeur
//
// copie l'address pointé dans Block
// initialise le pointeur sur l'addresse pointé
//////////////////////////////////////////////
template<class T>inline IPointer<T>::IPointer(T* Ptr)
{
    Block[this]=Ptr;
    m_Ptrs=Ptr;
}

////////////////////////////////////////////////
// constructeur par copie 
//  
// copie l'address pointé dans Block
// initialise le pointeur sur l'addresse pointé
//////////////////////////////////////////////                                                    
template<class T>inline IPointer<T>::IPointer(const  IPointer<T>& Ptr)
{
    Block[this]=Ptr;
    m_Ptrs=Ptr;
}
////////////////////////////////////////////
//operateur de  renvoit
//
// retourne la valeur pointée
//
// throw pointeur non initialisé
//////////////////////////////////////////////
template<class T>inline T& IPointer<T>::operator * ()const 
{
    if(m_Ptrs!=(T*)0)
    return  *m_Ptrs;
    throw m_Ptrs;
} 

////////////////////////////////////////////////////
//opérateur d'accès
//
// renvoie pointeur constant sur la donner
//////////////////////////////////////////////////////
template<class T>inline T* IPointer<T>::operator ->()const
{
    if(m_Ptrs!=(T*)0)
    return m_Ptrs;
    throw m_Ptrs;
}
////////////////////////////////////////////////////
//opérateur ++
//
// positionne le pointeur dans le tableau de +1
//////////////////////////////////////////////////////
template<class T>inline T IPointer<T>::operator ++ (int)
{
    if(m_Ptrs!=(T*)0)
    m_Ptrs++;
} 
////////////////////////////////////////////////////
//opérateur --
//
// positionne le pointeur dans le tableau de -1
//////////////////////////////////////////////////////
template<class T>inline T IPointer<T>::operator -- (int)
{
    if(m_Ptrs!=(T*)0)
    m_Ptrs--;
} 
//////////////////////////////////////////////////////
//opérateur de renvoit
//
//retourne le pointeur constant 
////////////////////////////////////////////////////////
template<class T>inline IPointer<T>::operator T*() const 
{
    return m_Ptrs;
}
//////////////////////////////////////////////////////////////// 
//opérateur égale
////////////////////////////////////////////////////////////////
template<class T>inline const IPointer<T>& IPointer<T>::operator =(const  IPointer<T>& Ptr)
{
    Block[this]=Ptr.m_Ptrs;
    m_Ptrs=Ptr.m_Ptrs;
    return *this;
}
//////////////////////////////////////////////////////////////// 
//opérateur égale
////////////////////////////////////////////////////////////////
template<class T>inline const IPointer<T>& IPointer<T>::operator = (T* Ptr)
{
    if(m_Ptrs!=Ptr)
     {
        Block[this]=Ptr;
        m_Ptrs=Ptr;
    }
    return *this;
}
//////////////////////////////////////////////////////////////// 
//fonction AddressSwap()
//
//échange d'addresse pointé 
////////////////////////////////////////////////////////////////
template<class T>inline void IPointer<T>::AddressSwap( IPointer& Ptr)
{   
    T* tem= m_Ptrs;
     m_Ptrs= Ptr.m_Ptrs;
     Ptr.m_Ptrs=tem;
   
}
//////////////////////////////////////////////////////////////// 
//fonction ValueSwap()
//
//échange de valeur pointé
////////////////////////////////////////////////////////////////
template<class T>inline void IPointer<T>::ValueSwap( IPointer& Ptr)
{
    if(m_Ptrs==((T*)0)||Ptr.m_Ptrs==((T*)0))
    throw(m_Ptrs,Ptr.m_Ptrs);
    
      T tem= *m_Ptrs;

  • m_Ptrs= *Ptr.m_Ptrs;
  • Ptr.m_Ptrs=tem;
} //////////////////////////////////////////////////////////////// //fonction ValueCmp // //Compare les valeur pointé //////////////////////////////////////////////////////////////// template <class T>inline bool IPointer<T>::ValueCmp(const IPointer& Ptr) { return (*Ptr.m_Ptrs==*m_Ptrs) ? 1 : 0; } #endif

Conclusion :


exemple d'utilisation :
#include <IPointer>
#include <iostream>



void param(const char _cCpar);//déclaration de param (fonction pour les testes voir plus bas)

int main(int ircv,char** arcv)
{
int Y=4444;
int X=1000;
IPointer<int>Ptrs1=&Y;
IPointer<int>Ptrs2 =&X;


std::cout<<"Ptrs1 : "<<Ptrs1<<" Ptrs1 : "<<*Ptrs1<<std::endl<<"Ptrs2 : "<<Ptrs2<<" Ptrs2 : "
<<*Ptrs2<<std::endl<<std::endl;
std::cout<<"Ptrs1.AddressSwap(Ptrs2);"<<std::endl<<std::endl;
Ptrs1.AddressSwap(Ptrs2);
std::cout<<"Ptrs1 : "<<Ptrs1<<" Ptrs1 : "<<*Ptrs1<<std::endl<<"Ptrs2 : "<<Ptrs2<<" Ptrs2 : " <<*Ptrs2<<std::endl<<std::endl;
std::cout<<"Ptrs1.ValueSwap(Ptrs2);"<<std::endl<<std::endl;
Ptrs1.ValueSwap(Ptrs2);
std::cout<<"Ptrs1 : "<<Ptrs1<<" Ptrs1 : "<<*Ptrs1<<std::endl<<"Ptrs2 : "<<Ptrs2<<" Ptrs2 : "<<*Ptrs2<<std::endl;
system("pause");
}

A voir également

Ajouter un commentaire

Commentaires

Messages postés
4
Date d'inscription
jeudi 10 décembre 2009
Statut
Membre
Dernière intervention
30 mai 2012

j ai trouver une erreur je ss pas ou ?
Messages postés
6
Date d'inscription
vendredi 9 janvier 2009
Statut
Membre
Dernière intervention
16 décembre 2009

Désoler, une erreur de syntaxe de ma part:

IPointer ptrMagique(&(new int[BCP]));
IPointer ptrMagique = &(new int[BCP]);

C'est l'addresse du pointeur qui est prise comme argument et non pas le pointeur. XD
Messages postés
6
Date d'inscription
vendredi 9 janvier 2009
Statut
Membre
Dernière intervention
16 décembre 2009

J'ai aussi un petit commentaire apropos de ton pointeur intelligent. Lorsque tu crée ton objet et affectes un pointeur, serait-il pas mieux si cela se fait dans le constructeur de la classe uniquement qui prend comme argument un pointeur vers le pointeur qui pointe sur la memoire hype? Comme ça, tu nullifie le pointeur antécédent, et en même temps tu t'assures que ton pointeur intélligent ne peut être changé par d'autres fonctions de la classe (sauf une fonction Release(); qui libère la mémoire heap prise et rend m_Ptrs = NULL;) ce qui rendra ton code plus sur. Ex:

IPointer::IPointer(T **ppT)
{
m_Ptrs = *pT;
*pT = 0;
}
IPointer::IPointer(const T **ppT)
{
m_Ptrs = *pT;
}

Le deuxième constructeur sera dans le cas du:

IPointer ptrMagique(new int[BCP]);
ou sont equivalent puisque le constructeur n'est pas déclaré "explicit"
IPointer ptrMagique = new int[BCP];

Tu vois c'est avant tout savoir l'utilisation du pointeur avant de créer la classe mais puisque c'est un util d'apprentissage je te comprends fort bien. Moi pour apprendre les templates j'ai créer mon propre array dynamique (mieux connu sous le nom dans STL de std::vector) :D.
Messages postés
10
Date d'inscription
vendredi 14 août 2009
Statut
Membre
Dernière intervention
31 mai 2010

Essayer d'implémenter un pointeur intelligent (de mauvaise facture) je ne dis pas non, mais pour une "vraie" utilisation utilise des trucs qui ont déjà fait leur preuves.
Par exemple boost.shared_ptr, boost.scoped_ptr, etc ...
Messages postés
216
Date d'inscription
samedi 11 août 2007
Statut
Membre
Dernière intervention
30 mai 2011

ok je voi mieux le problème, je vais regarder pour empècher deux foix la même allocation merci ^^
Afficher les 8 commentaires

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.