[658] | 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 |
|
---|