From 325530e630c68c7c10a2f4339f5b43434fcd0329 Mon Sep 17 00:00:00 2001 From: sc Date: Tue, 28 Nov 2000 14:19:35 +0000 Subject: Incorporation into IvyLeague Ccu -> Ivl ccu -> ivl Smart pointers disappear (too dangerous) Imakefile disappears (Makefile now) An empty cplus_bugs.h has been created locally --- utils/SmartPointer.cc | 290 -------------------------------------------------- 1 file changed, 290 deletions(-) delete mode 100644 utils/SmartPointer.cc (limited to 'utils/SmartPointer.cc') diff --git a/utils/SmartPointer.cc b/utils/SmartPointer.cc deleted file mode 100644 index 50343df..0000000 --- a/utils/SmartPointer.cc +++ /dev/null @@ -1,290 +0,0 @@ -/* - * CENA C++ Utilities - * - * by Stephane Chatty - * - * Copyright 1990-1995 - * Laboratoire de Recherche en Informatique (LRI) - * Centre d'Etudes de la Navigation Aerienne (CENA) - * - * smart pointers, originally by Michel Beaudouin-Lafon - * - * $Id$ - * $CurLog$ - */ - -#include -#include - -#ifdef __GNUG__ -#pragma implementation "SmartPointer.h" -#endif -#include "SmartPointer.h" -#include "List.h" - -CcuSmartData::check_type CcuSmartData::check = doWarn; -#ifdef OLD -int CcuSmartData::NextCreatedIsDynamic = 0; -#else -CcuList* CcuSmartData::LastDynamics; -#endif - -/*?class CcuSmartData -The class \typ{CcuSmartData} is the base class for objects that you want to reference through smart pointers. -Such an object contains a reference count. -This reference count contains the number of smart pointers to this object. -When that number reaches 0 and the object was allocated dynamically, it is safe to destroy it -(unless there are still plain pointers to it!). -Hence, a \typ{CcuSmartData} destroys itself when its reference count reaches 0 -and it was allocated dynamically (ie. with \fun{operator new}). - -To implement the reference counting properly, it is necessary to overload the assignment operator on -the reference count, so that when object \var{a} is assigned to object \var{b}, -the reference count of \var{b} does not change. -This means that all classes deriving from \typ{CcuSmartData} will have their assignment operator implicitly redefined. -This implies a small run-time overhead, and a special care if you need to overload this operator -in a derived class of \typ{CcuSmartData}. - -Another point needs special attention. The only way of deciding whether an object was dynamically -allocated is to redefine \fun{operator new}. This was done in \typ{CcuSmartData}. However, you might -want to define your own \fun{new} and \fun{delete} in derived classes. If you do so, you -should take care that \fun{new} sets the flag \var{CcuSmartData::NextCreatedIsDynamic} to a non-null value. -?*/ - -/*! -One big problem with smart pointers lies in making a distinction between -objects created in the stack (that we should not delete) and objects created -dynamically, that we should delete when no more referenced. There's no way -to make that distinction in constructors, sowe try to use operator new. This -works well only if the constructor is called right after operator new, which is not -always the case... -!*/ -void* -CcuSmartData :: operator new (size_t size) -{ -#ifdef OLD - NextCreatedIsDynamic = 1; - return ::operator new (size); -#else - int sz = (int) size; - void* p = ::operator new (sz); - if (!LastDynamics) - LastDynamics = new CcuList; - LastDynamics->Prepend (p); - return p; -#endif - -} - -/*? -Create a data, ie. initialize its reference count to 0. -?*/ -CcuSmartData :: CcuSmartData () -#ifdef OLD -: State (NextCreatedIsDynamic ? 0 : 1) -#else -: State (1) -#endif -{ -#ifdef OLD - NextCreatedIsDynamic = 0; -#else - if (LastDynamics && LastDynamics->Remove (this)) - State = 0; -#endif -} - -/*? -This is the copy constructor for the class \typ{CcuSmartData}. -Because there is a copy constructor defined, -all derived class will have a copy constructor defined implicitly, -unless you specify one explicitely. -?*/ -CcuSmartData :: CcuSmartData (const CcuSmartData&) -#ifdef OLD -: State (NextCreatedIsDynamic ? 0 : 1) -#else -: State (1) -#endif -{ -#ifdef OLD - NextCreatedIsDynamic = 0; -#else - if (LastDynamics && LastDynamics->Remove (this)) - State = 0; -#endif -} - -/*? -This is the destructor for class \typ{CcuSmartData}. It is {\em virtual}. -This destructor checks that the deleted object has a null reference count. -If not, it notifies the user according to the sanity check value defined with -the static member function \fun{SetCheck}. -Dynamically allocated \typ{CcuSmartData} objects are automatically deleted by the smart pointer package -when their reference count reaches zero. -?*/ -CcuSmartData :: ~CcuSmartData () -{ - if (State > 1) { - if (check >= doOnlyDynamic) { - if (IsDynamic ()) - fprintf (stderr, "*** ~CcuSmartData (0x%x) : ref count of dynamic object is %d !\n", this, int (State/2)); - else if (check >= doWarn) - fprintf (stderr, "*** ~CcuSmartData (0x%x) : ref count of global or automatic object is %d !\n", this, int (State/2)); - } - if (check == doAbort) { - fprintf (stderr, "*** aborting\n"); - abort (); - } - } -} - - -void -CcuSmartData :: DecrRef () -{ - State -=2; - if (State == 0) - delete this; -} - -#ifdef DOC -/*? -This protected member returns 1 if this object was allocated with \fun{operator new}. -?*/ -int -CcuSmartData :: IsDynamic () const -{ -} -#endif - - -/*? -This {\em static} member controls the sanity check done by the destructor of class \typ{CcuSmartData}: -a \typ{CcuSmartData} should not be destroyed when its refcount is non zero, because this means -that some smart pointers are still pointing at it. -Such errors can happen in two situations:\\ - \hspace*{0.5cm}1. when calling explicitely \fun{operator delete} on an object that has smart pointers to it;\\ - \hspace*{0.5cm}2. when a local object (an object on the stack) that has smart pointers to it is automatically -destroyed upon exit of its enclosing block.\\ -\vspace{0.5ex} -When an error occurs, the value of \var{chk} defines what happens, as follows:\\ - \hspace*{0.5cm}$\bullet$ if \var{t} is \var{doWarn}, a message is issued on \var{stderr} and processing continues;\\ - \hspace*{0.5cm}$\bullet$ if \var{t} is \var{doAbort}, a message is issued and and \fun{abort} is called, forcing a core dump;\\ -but not for dynamically allocated objects.\\ - \hspace*{0.5cm}$\bullet$ if \var{t} is \var{doOnlyDynamic}, checking is disabled for global and automatic objects, - \hspace*{0.5cm}$\bullet$ if \var{t} is \var{doNoCheck}, checking is disabled.\\ -\fun{SetCheck} returns the previous value of the checking status. -The initial value is 0 (warning message). -?*/ -CcuSmartData::check_type -CcuSmartData :: SetCheck (check_type t) -{ - check_type old = check; - check = t; - return old; -} - -/*?class CcuSmartPointerTo -The class \typ{CcuSmartPointerTo} is the smart pointer class itself. -A \typ{CcuSmartPointerTo} object contains a pointer to a \typ{DATA} object. -?*/ - -#ifdef DOC - -/*? -Construct a null smart pointer. -?*/ -CcuSmartPointerTo :: CcuSmartPointerTo () -{ -} - -/*? -Construct a smart pointer to data \var{d}. -\var{d} may be 0. -?*/ -CcuSmartPointerTo :: CcuSmartPointerTo (DATA* d) -{ -} - -/*? -This is the copy constructor for smart pointers. -It ensures that the reference counts are properly updated when a smart pointer -is initialized by copy (argument passing and function return for instance). -?*/ -CcuSmartPointerTo :: CcuSmartPointerTo (const CcuSmartPointerTo& p) -{ -} - -/*? -The destructor updates the reference count of the pointed to data, -and destroys it if the reference count reaches 0 and the data was dynamically allocated. -?*/ -CcuSmartPointerTo :: ~CcuSmartPointerTo () -{ -} - -/*? -This operator overloads the assignment of smart pointers. -It can destroy the data pointed by the left-hand side pointer if its reference count reaches 0. -?*/ -CcuSmartPointerTo& -CcuSmartPointerTo :: operator = (const DATA* d) -{ -} - -/*? -This operator overloads the dereferencing of smart pointers. -Unfortunately, it returns a \typ{DATA*} where one would prefer a pointer to a derived class of \typ{DATA}. -This problem, which occurs also with the overloading operators below, -is fixed by the generic pointer class (\fun{PointerClass}) described below. -?*/ -DATA* -CcuSmartPointerTo :: operator -> () -{ -} - -/*? -These conversion operators make it possible to pass a pointer to data where a smart pointer is expected. -They also make it possible to test a smart pointer like a usual pointer. -?*/ -CcuSmartPointerTo :: operator DATA* () -{ -} - -// note: this is hacked up for the doc stuff -/*? -This is a macro to generate a smart pointer class. -\typ{SmartClass} is the name of the class to generate, -and \typ{DataClass} is the name of the class to which \typ{SmartClass} objects will point. -\typ{DataClass} must derive from \typ{DATA}. -The generated class is similar to the class \typ{CcuSmartPointerTo} described above, -with \typ{CcuSmartPointerTo} replaced by \typ{SmartClass} and \typ{DATA} replaced by \typ{DataClass}. -In particular, this means that such smart pointers can be dereferenced with the \fun{operator ->} -like usual pointers. -?*/ -generic -PointerClass (SmartClass, DataClass) -{ -} - -/*? -This macro is similar to \fun{PointerClass} described above. -It generates a smart pointer class named \typ{SmartClass} -for the class \typ{DataClass}. -Unlike the previous macro, the generated class is not a base class, -but instead a derived class of \typ{SmartBaseClass}, -which must be a smart pointer class itself. -If \typ{pA} is a smart pointer class to class \typ{A} and \typ{B} derives from \typ{A}, -you can declare a smart pointer class \typ{pB} to the class \typ{B} with:\\ -\hspace*{1cm}\com{DerivedPointerClass (pB, pA, A)}\\ -Then \typ{pB} objects can be used where \typ{pA} objects are expected, -which would not be the case if \typ{pB} was declared with \fun{PointerClass}. -?*/ -generic -DerivedPointerClass (SmartClass, BaseSmartClass, DataClass) -{ -} - -#endif - -- cgit v1.1