Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members

RCBase< Type > Class Template Reference

An abstract base class for reference counted arrays. More...

#include <RCBase.h>

Inheritance diagram for RCBase< Type >:

Inheritance graph
[legend]
List of all members.

Public Member Functions

virtual Type read (const int i) const=0
virtual void write (const int i, const Type v)=0

Detailed Description

template<class Type>
class RCBase< Type >

An abstract base class for reference counted arrays.

These array objects implement copy-on-write semantics.

This abstract class defines two pure virtual functions, read and write and the local ValRef class. The ValRef class is returned for referenced array elements. This class is a proxy which avoids copy-on-read.

An object that implements copy-on-write arrays defines the [] operator (the index operator). The index operator can be used on either the right or left hand size of an assignment. For example, in the statements below a is an instance of an object that implements the index operator.

MyObj b = a; // b is a reference to a MyType v = a[i]; // A right-hand-side reference a[j] = v; // A left-hand-size reference

References counted objects share a reference to common data until an object is modified. The copy-on-write semantics means that a unique copy will be made before shared object is modified. Ideally this saves memory and improves performance.

In the example above a and b share a reference to the same data set. When a is read, there should be no effect (other than the read). However, when a is modified (by being written), a unique copy is made first. Although previously a and b referenced the same data, the write operation will force the creation of a unique copy for a and only a will be modified. The b object will retain its previous value.

In a better world there would be some way that the programmer could indicate to the C++ compiler that a particular operator [] function implements the right-hand-side or the left-hand-size semantics.

The naive implementation (which I used in the first two versions of a String class) turns out to be wrong. Here is the slightly simplified code from this somewhat incorrect String class. My intention was that the operator [] function below labeled "LHS" would implement copy-on-write. The operator [] labeled RHS would do a read and nothing more.

This code does not properly implement copy-on-write

// // operator [] (RHS) with an integer index // inline char String::operator [](const int ix) const { return pShare->str[ix]; }

// // operator[] (LHS), integer index // inline char & String::operator [](const int ix) { makeUnique(); // make a unique copy of the shared data return pShare->str[ix]; } // operator []

As it turned out, the function labeled LHS is called in most cases, whether the operator [] is on the left or right hand side of the expression. This results in copy-on-read which is, obviously, not desirable and destroys much of the utility for a reference counted object.

The proper implementation of the String object uses an instance of the ValRef object (instantiated for char).

inline String::ValRef String::operator[](const int ix) { return ValRef( *this, ix ); }

The ValRef object is losely modeled after the Cref class in The C++ Programming Language, Third Edition by Bjarne Stroustrup, Section 11.12.

Author:
Ian Kaplan www.bearcave.com

Definition at line 112 of file RCBase.h.


Member Function Documentation

template<class Type>
virtual Type RCBase< Type >::read const int  i  )  const [pure virtual]
 

Implemented in RCArray< T >, RCArray< double >, and RCArray< char >.

Referenced by RCBase< Type >::ValRef::operator Type().

template<class Type>
virtual void RCBase< Type >::write const int  i,
const Type  v
[pure virtual]
 

Implemented in RCArray< T >, RCArray< double >, and RCArray< char >.

Referenced by RCBase< Type >::ValRef::operator=().


The documentation for this class was generated from the following file:
Generated on Mon Sep 22 20:23:02 2003 by doxygen 1.3.3