Listing 1 (cow.h) Header for Copy-On-Write Base Classes

#ifndef COW_H             //  prevent multiple includes
#define COW_H

//  Obj_COW - a real object (for use by virtual objects)
class Obj_COW {
   //  Allow virtual object access to real obj
   friend class Obj_Virt;
protected:
   //  Constructors and destructor
   Obj_COW(void) { count = 0; }
   //  Functions
   virtual Obj_COW *dup(void) = 0;
private:
   //  Data
   short count;           //  Count of uses
};

//  Obj_Virt - a virtual object (points to the real object)
class Obj_Virt {
protected:
   //  Constructors and destructor
   Obj_Virt(void) { po= NULL; }
   Obj_Virt(const Obj_Virt& vo) { set_ptr(vo.po); }
   ~Obj_Virt(void) { release(); }
   // Functions
   Obj_Virt&  operator = (Obj_Virt& vo)
              { set_ptr(vo.po); return(*this); }
   Obj_COW    *get_ptr(void) { return(po); }
   void       print(void);
   void       release(void);
   void       set_ptr(Obj_COW *pobj);
   void       split(void);
private:
   //  Data
   Obj_COW *po;           //  Pointer to real object
};

//  Obj_Virt::print - print current values
void Obj_Virt::print(void)
{
   printf("po = %p, count = %d\n", po, po->count);
}

//  Obj_Virt::release - release the real object
//                      for this virtual object
inline void Obj_Virt::release(void)
{
   if (NULL != po) {

      //  Decrement count; delete object if zero
      if (0 == --po->count) {
         delete po;
      }
      po = NULL;
   }
}

//  Obj_Virt::set_ptr - do a virtual copy of a real object
inline void Obj_Virt::set_ptr(Obj_COW *pobj)
{
   release();      //  Release current object, if any
   po = pobj;
   po->count++;
}

//  Obj_Virt::split - create a new real object if needed
inline void Obj_Virt::split(void)
{
   if (1 < po->count) {    //  Only split if count > 1
      po->count--;
      po = po->dup();
      po->count = 1;
   }
}

#endif /* COW_H */

//  End of File