| [228] | 1 | #ifndef PREFCOUNT_H | 
|---|
|  | 2 | #define PREFCOUNT_H | 
|---|
|  | 3 |  | 
|---|
|  | 4 | // Classe d'objet avec comptage de référence. | 
|---|
|  | 5 | // Le nombre de référence est incrémenté lors de la création et lors d'un Attach | 
|---|
|  | 6 | // (inutile d'appeler Attach si on crée l'objet). | 
|---|
|  | 7 | // Si on cree l'objet avec isTmp = true, alors le possesseur est temporaire, | 
|---|
|  | 8 | // et en tout cas, possede le PRefCount en lecture seule. | 
|---|
|  | 9 | // Par exemple, une fonction qui retourne un objet de type PRefCounted le créera | 
|---|
|  | 10 | // en mode temporaire. Un constructeur par copie appelé derrière ne dupliquera pas | 
|---|
|  | 11 | // les données. | 
|---|
|  | 12 | // HasTmpOnly retourne true si un objet n'est référencé que de façon temporaire. | 
|---|
|  | 13 |  | 
|---|
|  | 14 | #ifdef TRACE_REFCOUNT | 
|---|
|  | 15 | #define DBG_DESTROY cerr << "PRefCounted destroyed" << endl; | 
|---|
|  | 16 | #define DBG_ATTACH  cerr << "PRefCounted attached" << endl; | 
|---|
|  | 17 | #define DBG_DETACH  cerr << "PRefCounted detached" << endl; | 
|---|
|  | 18 | #else | 
|---|
|  | 19 | #define DBG_DESTROY | 
|---|
|  | 20 | #define DBG_ATTACH | 
|---|
|  | 21 | #define DBG_DETACH | 
|---|
|  | 22 | #endif | 
|---|
|  | 23 |  | 
|---|
|  | 24 |  | 
|---|
|  | 25 | class PRefCounted { | 
|---|
|  | 26 | public: | 
|---|
|  | 27 | PRefCounted(bool isTmp=false) | 
|---|
|  | 28 | :refcount(1), tmpcount(isTmp?1:0) {} | 
|---|
|  | 29 | virtual                      ~PRefCounted()           {DBG_DESTROY} | 
|---|
|  | 30 |  | 
|---|
|  | 31 | void                         Attach(bool isTemp=false) | 
|---|
|  | 32 | {if (isTemp && HasTmpOnly()) tmpcount++; | 
|---|
|  | 33 | DBG_ATTACH | 
|---|
|  | 34 | refcount++;} | 
|---|
|  | 35 | void                         Detach()                 {refcount--; | 
|---|
|  | 36 | DBG_DETACH | 
|---|
|  | 37 | if (!refcount) delete this;} | 
|---|
|  | 38 |  | 
|---|
|  | 39 | int                          RefCount() const         {return refcount;} | 
|---|
|  | 40 | bool                         HasTmpOnly() const       {return tmpcount == refcount;} | 
|---|
|  | 41 |  | 
|---|
|  | 42 | private: | 
|---|
|  | 43 | int refcount; | 
|---|
|  | 44 | int tmpcount; | 
|---|
|  | 45 | }; | 
|---|
|  | 46 |  | 
|---|
|  | 47 | // Macro pour les constructeurs par copie d'objets référençant des PRefCounted | 
|---|
|  | 48 | // Il faut que le PRefCounted ait une méthode T* Clone(bool isTmp); | 
|---|
|  | 49 |  | 
|---|
|  | 50 | template <class refcount> | 
|---|
|  | 51 | void PRefCountCopy(refcount*& dest, refcount const* src, bool isTmp=false) { | 
|---|
|  | 52 | if (dest) dest->Detach(); | 
|---|
|  | 53 | if (!src) { | 
|---|
|  | 54 | dest=0; | 
|---|
|  | 55 | } else if (src->HasTmpOnly()) { | 
|---|
|  | 56 | dest = const_cast<refcount*>(src); | 
|---|
|  | 57 | dest->Attach(isTmp); | 
|---|
|  | 58 | } else { | 
|---|
|  | 59 | dest = src->Clone(isTmp); | 
|---|
|  | 60 | } | 
|---|
|  | 61 | } | 
|---|
|  | 62 |  | 
|---|
|  | 63 |  | 
|---|
|  | 64 | #endif | 
|---|
|  | 65 |  | 
|---|