Click Here!
home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
[an error occurred while processing this directive]
Previous Table of Contents Next



Notable items in this file are the calls to reference() and dereference() in the assignment operator and copy constructor. The object references the other object while it is working on it to prevent a dereference() call in another thread from destroying the object while the copying is in progress.
There is one problem with this code. Can you spot it? (Feel free to skip the rest of this paragraph until you have played with the code.) The process of copying can destroy an object with no other references. Because a newly created object has a reference count of 0, referencing and then dereferencing the object in any way will cause the object to self-destruct. To fix it, make the copy constructor or assignment operator grab the mutex that protects the reference count variable, increment copyfrom. Refs, and free the mutex. Decrement the Refs variable at the end of the function, remembering the mutexes. This has the effect of bypassing the self-destruct code in the dereference() function.
6.  Implement a program to test the classes. This program reads 200 words from a file (I chose the source file for the test program), and writes them back to the screen as just words with line wrapping, and then counts the lines as it goes. This is something I wish every email editor could do with quoted text. Here is the listing for the test program for our class, refcount.cpp:
// File: refcount.cpp
// A program that uses our reference counting class.
// Copyright 1998, Jan Walter
// NO WARRANTY. If this code breaks you get to keep both pieces.

// Compiler verificiation:
// Borland C++ 5.01A:             Yes
// DJGPP 2.01 w. GCC 2.81 :     Yes
// Microsoft VC++ 5:                Not Tried
// GCC 2.7.2/Linux:                Not tried
// GCC/EGCS/Linux:                Yes

#include <iostream>
#include <fstream>

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#include “memclass.hpp”

typedef ObjectContainer<string> StringC ;
typedef ObjectPtr<string>          StringP ;

const int numstrings = 200 ;
StringC* stringlist[ numstrings ] ;

int main( int, char** )
{
    ifstream infile( “refcount.cpp”, ios::in | ios::nocreate ) ;

   for ( int i = 0 ; i < numstrings ; i++ )
   {
       string temp ;
      infile >> temp ; // grab a word from our file
      stringlist[i] = new StringC( new string(temp), 1 ) ;

   }

   int lines = 0, width = 3 ;

   cout << (lines + 1) << “ :” ;

   for ( int i = 0 ; i < numstrings ; i++ )
   {
       StringP ourstring( stringlist[i] ) ;

	// determine how far along on the line we are ...
      width += ourstring->length() + 1 ;

      if( width > 75 )
      {
	  lines ++ ;
	 cout << endl << (lines + 1) << “ :”;
	 width = ( ourstring->length() + 3 ) ;
      }
      else
	  cout << ‘ ‘ ;

      cout << *ourstring ;

   }

   cout     << endl
	 << endl
	 << “Statistics: “ << endl
	 << “Total lines output: “ << (lines + 1) << endl ;

    return 0;
}
// end of file

The program file shows the use of typedefs to make the use of template classes a bit easier on the reader and the keyboard. The objects contained in the renamed ObjectContainer are deleted at the end of the second for loop, one at a time, as the program traverses the array.

How It Works

The trick with the classes as they are presented is to determine when to count references. The easiest way to accomplish this is to make a pointer class to encapsulate pointer functionality.

The pointer objects can be created and fall out of scope ad nauseum, and the data will be valid until the last pointer object is deleted. At that point, the container object will self-destruct.

The classes effectively deal with a number of problem areas:

  Automatic cleanup of objects external to the scope in which they are being accessed (essentially primitive garbage collection).
  With mutexes implemented, provide thread safe access to dynamically allocated memory.
  Prevent the overwriting of memory currently being referred to elsewhere. The assignment operator of the ObjectContainer class will throw a logic_error exception if this is the case.

Comments

It is possible to accidentally grab a pointer to the data contained that’s not accounted for through the overloaded operators of the ObjectPtr class. This is difficult to prevent. Having said this, it is not likely to happen if the programmer using the class understands the implications of the code. After all, it is possible to access private data members of classes from outside a class, too (by typecasting the object to an array of char, and then reading it as an array).

Also, the data object being encapsulated within the ObjectContainer might need mutex protection for the data it contains. Because this is a data issue, I recommend that the data class handle this and not the container class.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.