1 #include <stdio.h> 2 #include <iostream> 3 using namespace std; 4 5 class IntegerPtr; 6 7 /* 8 Integer est une classe qui enveloppe un int, elle garde aussi le compte du nombre 9 d'objets de type IntegerPtr qui pointent sur elle 10 Le constructeur est privé: seuls les IntegerPtr, qui sont amis d'Integer, 11 ont le droit d'utiliser cet objet 12 */ 13 14 class Integer { 15 public: 16 friend class IntegerPtr; 17 18 private: 19 Integer(int x) : i(x),count(0) {}; 20 21 int i; 22 unsigned int count; 23 }; 24 25 /* IntegerPtr est une classe qui encapsule un pointeur sur Integer. 26 C'est le seul moyen d'utiliser Integer */ 27 28 class IntegerPtr { 29 public: 30 31 /* Le constructeur incrémente le comptage, il est initialisé à partir d'un int */ 32 IntegerPtr(int i) : ptr(new Integer(i)){ 33 if (ptr!=NULL) 34 ptr->count++; 35 } 36 37 /* Le destructeur décrémente le comptage, et supprime l'objet si celui-ci vaut 0 */ 38 ~IntegerPtr() { 39 if (ptr !=NULL && --ptr->count==0) 40 delete ptr; 41 } 42 43 /* Le constructeur de copie incrémente lui aussi le comptage */ 44 IntegerPtr(const IntegerPtr& ip): ptr(ip.ptr) { 45 if (ptr != NULL) 46 ptr->count++; 47 } 48 49 /* L'operateur = doit etre redefini, il decremente l'ancien comptage, re-incremente le nouveau */ 50 IntegerPtr& operator=(const IntegerPtr& ip) { 51 if (this == &ip) return *this; // Attention !!! self-assignment 52 if (ptr != NULL && --ptr->count==0) 53 delete ptr; 54 if (ip.ptr != NULL) 55 ++ip.ptr->count; 56 ptr = ip.ptr; 57 return *this; 58 } 59 60 /* On doit redefinir l'operateur * pour pouvoir utiliser Integer */ 61 int& operator*() { return ptr->i; }; 62 const int& operator*() const {return ptr->i; }; 63 64 private: 65 Integer* ptr; 66 }; 67 68 int main() 69 { 70 IntegerPtr i = 4; 71 IntegerPtr j = 4; 72 IntegerPtr k = *i + *j; 73 cout << *k << '\n'; 74 IntegerPtr l = k; 75 }