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 }