Pas de soucis ;) Tout est bon pour apprendre :ccool:
Version imprimable
Salut,
1/En général, on n'utilise pas le même pointeur intelligent pour un pointeur et un tableau. Tu devrais avoir un GCPointer et un GCPtrArray.
2/_msize c'est du Microsoft spécifique.
3/__GC : la norme interdit de débuter ses identificateurs par '__', cf FAQ.
4/ Pour l'opérateur d'affectation, tu pourrais employer l'idiom copy and swap (cf FAQ)
5/ Pour renforcer ton typage et te passer de GCDestructor, tu devrais utiliser un wrapper et le type erasure de l'article de Alp :Code:
1
2
3
4
5
6
7
8 template<class T> GCPointer<T> &GCPointer<T>::operator =(const GCPointer<T> &ptr) { GCPointer<T> tmp(ptr); std::swap(membre_1,tmp.membre_1); std::swap(membre_2,tmp.membre_2); //...
Ensuite dans GCPointer, tu remplaces T *m_pTPointer par CPtrWrapper<T> *m_pTPointerCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 struct IPtrWrapper { virtual ~IPtrWrapper()=0; }; template<class T> struct CPtrWrapper { T*ptr; ~CPtrWrapper() { delete ptr; } private: CPtrWrapper(CPtrWrapper const &); CPtrWrapper&operator=(CPtrWrapper const &); };
Et dans SimpleGC, tu définis ta map comme suit :
Plus besoin du DoGCDestructor, plus besoin des casts (un pointeur en int:sm:), plus de soucis, tout est correctement typé.Code:typedef std::map<IPtrWrapper*,unsigned int> objects_map;
Attention, dans UpdateReferenceCounter, tu fais
Si pobject n'est pas une clé existante, une nouvelle entrée est créé. Cependant je ne suis pas persuadé que la valeur pour second soit toujours 0 ! Tu devrais explicitement distinguer le cas de création d'une clé de celui de mise à jour du compteur.Code:objmap[pobject] += value;
Corrige moi, stp, si je me trompe...
- GC et GCPointer travaillent seulement avec CPtrWrapper et son interface.
- Quand on affecte une valeur à GCPointer on la place dans un objet CPtrWrapper et l'adresse de l'objet est stoquée par GC pour compter le nombre de référence.
- Quand un GCPointer est mis à NULL ou detruit son ref count et à zero et GC va detruire son IPtrWrapper ce qui revient en même de detruire l'objet CPtrWrapper.
Conclusion, le type de données n'est plus considéré!
Ai-je bien capter?...
Je vais reporter les remerciéments après ta réponse...:)
Salut,
En gros, c'est ça.
Merci 3DArchi pour tout...
Merci pour l'analyse de mon code, les conseils, les corrections et les suggestions...
Salut,
Pour continuer dans ton projet, il serait intéressant de surcharger les opérateurs globaux new/new[] et delete/delete[] pour que l'enregistrement vers ton GC se fasse automatiquement (en invoquant le GC dans cette surcharge).
Autre remarque : l'appel au destructeur se fait au moment où tu récupères la mémoire. C'est un comportement de Java, mais assez inhabituel au C++ où on s'attend à ce que le destructeur soit appelé au moment où on demande la libération du pointeur. Ca peut être perturbant. Rien n'empêche d'appeler le destructeur explicitement et de ne libérer la mémoire que plus tard (à articuler avec la suggestion précédente de surcharge des opéreteurs delete).
Enfin, tu pourrais apporter un peu de généricité à ton GC en 'politisant' la récupération de la mémoire (tuto sur les classes politiques).
Voilà quelques idées pour occuper ces mois d'été :mrgreen: