Ma class de pointeurs intelligents

Ma class de pointeurs intelligents - C++ - Programmation

Marsh Posté le 03-12-2006 à 16:47:54    

Hello.
 
J'ai fait une classe de pointeur intelligent avec compteur de référence et j'aimerais bien savoir ce que vous en pensez.  

Code :
  1. struct arrayPtr{static bool array;};
  2. bool arrayPtr::array = true;
  3. struct noArrayPtr{static bool array;};
  4. bool noArrayPtr::array = false;
  5. template <class T, class Policy = noArrayPtr> class CSmartPtr
  6. {
  7. public:
  8.  //Constructors and destructor :   
  9.  CSmartPtr(void);
  10.  CSmartPtr(T *Pointer);
  11.  CSmartPtr(const CSmartPtr & );
  12.  ~CSmartPtr(void);
  13.  //Others operators on the pointers :
  14.  const CSmartPtr& operator=(const CSmartPtr & );
  15.  T* operator->(void) const;
  16.  T& operator*(void) const;
  17.  T** operator&(void) const;
  18.  //Comparison :
  19.  bool operator==(const T & ) const;
  20.  bool operator!=(const T & ) const;
  21.  bool operator!(void) const;
  22.  //Casting :
  23.  operator T*(void) const;
  24. private:
  25.  T *data;
  26.  int *ref;
  27. };
  28. //-----------------------------------------------------------------------
  29. // Constructors and destructor  
  30. //-----------------------------------------------------------------------
  31. template<class T, class Policy> inline CSmartPtr<T, Policy>::CSmartPtr(void) : data(NULL), ref(NULL)
  32. {
  33. }
  34. template<class T, class Policy> inline CSmartPtr<T, Policy>::CSmartPtr(T *pointer) : data(pointer), ref(new int(1))
  35. {
  36. }
  37. template<class T, class Policy> inline CSmartPtr<T, Policy>::CSmartPtr(const CSmartPtr &copy) : data(copy.data), ref(copy.ref)
  38. {
  39. if(ref)
  40.  (*ref)++;
  41. }
  42. template<class T, class Policy> inline CSmartPtr<T, Policy>::~CSmartPtr(void)
  43. {
  44. if(ref && (--(*ref) == 0))
  45. {
  46.  delete ref;
  47.  if(Policy::array)
  48.   delete [] data;
  49.  else
  50.   delete data;
  51. }
  52. }
  53. //-----------------------------------------------------------------------
  54. // Others operators on the pointers
  55. //-----------------------------------------------------------------------
  56. template<class T, class Policy> inline const CSmartPtr<T, Policy>& CSmartPtr<T, Policy>::operator=(const CSmartPtr &copy)
  57. {
  58. if(ref && (--(*ref) == 0))
  59. {
  60.  delete ref;
  61.  if(Policy::array)
  62.   delete [] data;
  63.  else
  64.   delete data;
  65. }
  66. data = copy.data;
  67. ref = copy.ref;
  68. if(ref)
  69.  (*ref)++;
  70. return *this;
  71. }
  72. template<class T, class Policy> inline T* CSmartPtr<T, Policy>::operator->(void) const
  73. {
  74. return data;
  75. }
  76. template<class T, class Policy> inline T& CSmartPtr<T, Policy>::operator*(void) const
  77. {
  78. return *data;
  79. }
  80. template<class T, class Policy> inline T** CSmartPtr<T, Policy>::operator&(void) const
  81. {
  82. return &data;
  83. }
  84. //-----------------------------------------------------------------------
  85. // Comparison
  86. //-----------------------------------------------------------------------
  87. template<class T, class Policy> inline bool CSmartPtr<T, Policy>::operator==(const T &other) const
  88. {
  89. return (data == other.data);
  90. }
  91. template<class T, class Policy> inline bool CSmartPtr<T, Policy>::operator!=(const T &other) const
  92. {
  93. return !(data == other.data);
  94. }
  95. template<class T, class Policy> inline bool CSmartPtr<T, Policy>::operator!(void) const
  96. {
  97. return data == 0;
  98. }
  99. //-----------------------------------------------------------------------
  100. // Casting
  101. //-----------------------------------------------------------------------
  102. template<class T, class Policy> inline CSmartPtr<T, Policy>::operator T*(void) const
  103. {
  104. return data;
  105. }


 
- Voyez-vous des erreurs ou des améliorations possible à faire ?
- Y a-t-il des choses que l'ont peut faire avec un pointeur normal et qu'ont ne peut pas faire avec ma classe ?
 
Quand je fait ceci, j'ai une erreur à la compilation, comment pourrait-je régler le problème ? :
CSmartPtr<float> pf;
CSmartPtr<int> pi2(new int);
pf = (float *)pi2;
 
En vous remerciant.


Message édité par vincent0 le 03-12-2006 à 23:20:36
Reply

Marsh Posté le 03-12-2006 à 16:47:54   

Reply

Marsh Posté le 03-12-2006 à 17:12:01    

C'est pas le principe de l'auto_ptr de la STL?
 
Je ne comprends pas le fonctionnement du compteur ref (surtout en ref* totalement maso).
 
Ca ne fait aucune distinction entre pointeur volatile, de pile et de tas, alloué ou non alloué (faire un delete sur un pointeur non alloué avec new c'est le crash assuré).
 
y en a qui vont te dire d'utiliser boost.
 
Edit: ah et puis le compteur ne distingue pas si c'est le même pointeur qu'on affecte ou un autre. Vraiment je ne comprends la logique.


Message édité par slash33 le 03-12-2006 à 17:22:48
Reply

Marsh Posté le 03-12-2006 à 17:41:33    

- "C'est pas le principe de l'auto_ptr de la STL?" Non, avec auto_ptr on ne peut avoir qu'un seul pointeur valide vers le même objet...
- "y en a qui vont te dire d'utiliser boost" Oui peut-être mais je fait surtout ça pour apprendre.
 
"ref" est un compteur qui compte le nombre de fois que l'objet est pointé.
Donc quand "ref" arrive à 0, on peut faire un delete de l'objet.
 
Exemple:
{
CSmartPtr<int> pi(new int); //ref=1 (pi pointe vers un int)
CSmartPtr<int> pi2 = pi; //ref=2 (pi et pi2 pointe vers le même int)
} //pi est detruit donc ref est décrémenté de 1, ensuite pi2 est detruit donc ref tombe à 0 et je supprime le "int".
 
Est-ce plus clair ?


Message édité par vincent0 le 03-12-2006 à 17:42:41
Reply

Marsh Posté le 03-12-2006 à 20:28:50    

Code :
  1. {
  2. CSmartPtr<int> pi(new int);
  3. int mon_int = -1234;
  4. CSmartPtr<int> pi2(&mon_int);
  5. // pi est détruit, le pointeur est libéré
  6. // pi2 est détruit, le système crash
  7. }

Reply

Marsh Posté le 03-12-2006 à 20:55:47    

en même temps boost::shared_ptr<> doit se comporter de la même manière si tu lui passes un pointeur qui pointe sur un truc temporaire.

Reply

Marsh Posté le 03-12-2006 à 22:37:47    

D'ailleur je ne pense pas que ça possible de régler ce problème !?
 
Personne ne sais comment je pourrait permettre ce genre de chose ? :
CSmartPtr<float> pf;
CSmartPtr<int> pi2(new int);
pf = (float *)pi2;

Reply

Marsh Posté le 03-12-2006 à 22:40:37    

bin c'est un peu dangeureux dans l'idée :D

Reply

Marsh Posté le 03-12-2006 à 23:22:30    

bjone a écrit :

bin c'est un peu dangeureux dans l'idée :D


Oui mais bon ça fonctionne quand même avec les pointeurs normals :D
 
Je vient d'éditer mon premier message en mettant la nouvelle version de ma classe CSmartPtr qui peut maintenant fonctionner avec des tableaux, qu'en pensez-vous ?:
CSmartPtr<float, arrayPtr> pi = new float[30];
CSmartPtr<float, noArrayPtr> pi2 = new float;
CSmartPtr<float> pi3 = new float;

Message cité 1 fois
Message édité par vincent0 le 03-12-2006 à 23:25:56
Reply

Marsh Posté le 04-12-2006 à 19:28:56    

vincent0 a écrit :

Oui mais bon ça fonctionne quand même avec les pointeurs normals :D


Tout dépend de ce qu'on entend par fonctionner, parce que c'est l'exemple type d'aliasing.
 
Note: un pointeur normal, des pointeurs normaux.

Reply

Marsh Posté le 04-12-2006 à 19:47:50    

[:drapal]


---------------
Töp of the plöp
Reply

Marsh Posté le 04-12-2006 à 19:47:50   

Reply

Marsh Posté le 04-12-2006 à 20:00:16    

J'ai un autre problème moins dangereux et plus important (comme ça tout le monde sera heureux ;) )
 

Code :
  1. class A
  2. {
  3. };
  4. class B : public A
  5. {
  6. };
  7. //....
  8. CSmartPtr<A> p1;
  9. CSmartPtr<B> p2 = new B;
  10. p1 = p2;


 
Comment feriez-vous pour que ce code compile et fonctionne correctement ? merci...


Message édité par vincent0 le 04-12-2006 à 20:00:53
Reply

Marsh Posté le 04-12-2006 à 20:08:09    

/o\

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed