From: skip@taygeta.oc.nps.navy.mil (Skip Carter)
Newsgroups: comp.lang.c++
Subject: Re: Reference counting for vectors, (Tony Hansen's book).
Date: 18 Aug 92 19:18:18 GMT
Reply-To: skip@taygeta.oc.nps.navy.mil (Skip Carter)

In article <BRISTER.92Aug14110706@tirade.decwrl.dec.com>, brister@decwrl.dec.com (James Brister) writes:
...
|> 
|> I do remember seeing an article in a magazine a while back about COW (copy
|> on write), where the new array (i.e. 'B' here)
|> 
|> > 	vector B = A; 
|> 
|> would release the referrence and make a duplicate of the real data if any
|> data was going to be modified. Unfortuantely I can't remember the details
|> right now of how it worked, but it didn't seem too tough to do.
|> 
|>

	The article was in the Aug 1991 issue of the C Users Journal,
	(see that article for details)   here are the base classes that are
	 required (I have used them to implement a Vector class as was 
	described in the original posting),

// cow.hpp	the definition of a Copy-On-Write object
//		see C Users Journal, Aug 1991

//	modified so that ~Obj_COW() is virtual so that the actual objects
//		 destructor is called			EFC  15 May 1992
//	make get_ptr() a const function			EFC  21 May 1992

// rcsid: $Id$ @(#)cow.hpp	1.2 23:05:28 5/21/92  EFC

#ifndef _COW_HPP
#define _COW_HPP

#include <stdlib.h>
#ifdef __ZTC__
#include <stdio.h>
#endif

class Obj_COW		// a real object, for use by virtual objects
{
	friend class Obj_Virt;	// allow virtual object to access real object
    private:
         short count;		// count of uses
    protected:
         Obj_COW(void) {count = 0;}
         virtual ~Obj_COW() {}
         virtual Obj_COW *dup(void) = 0;
};

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

#endif


// cow.cpp	implementation of part of the Copy-On-Write
//		class handler

static const char rcsid[] = "$Id$ @(#)cow.cpp	1.2 23:05:43 5/21/92  EFC";

#include <classlib/cow.hpp>

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

// release the real object for this virtual object
void Obj_Virt::release(void)
{
         if ( NULL != po )
        {
        	// decrement count, delete object of zero
                if ( 0 == --po->count )
                	delete po;
                po = NULL;
       }
}

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

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



 
 Everett (Skip) Carter             Phone:  408-646-3318 FAX: 408-646-2712
 Naval Postgraduate School         INTERNET: skip@taygeta.oc.nps.navy.mil
 Dept. of Oceanography, Code OC/CR  UUCP:     ...!uunet!taygeta!skip
 Monterey, CA. 93943               TELEMAIL: s.carter/omnet
Newsgroups: comp.lang.c++