From e35bbf091f97df89722941e40113960a7eb08d2c Mon Sep 17 00:00:00 2001 From: wolf Date: Tue, 15 Dec 1998 22:42:47 +0000 Subject: [PATCH] Minor restructuring, mostly cleanups. git-svn-id: https://svn.dealii.org/trunk@712 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/base/include/base/smartpointer.h | 154 ++++++++++++++------- deal.II/base/include/base/smartreference.h | 2 +- deal.II/base/include/base/subscriptor.h | 102 +++++++------- deal.II/base/source/subscriptor.cc | 40 ++++++ 4 files changed, 201 insertions(+), 97 deletions(-) create mode 100644 deal.II/base/source/subscriptor.cc diff --git a/deal.II/base/include/base/smartpointer.h b/deal.II/base/include/base/smartpointer.h index eb246ff1a7..4051d83c62 100644 --- a/deal.II/base/include/base/smartpointer.h +++ b/deal.II/base/include/base/smartpointer.h @@ -32,80 +32,138 @@ * } * delete p; * \end{verbatim} + * + * Note that a smart pointer can handle #const#ness of an object, i.e. + * a #SmartPointer# really behaves as if it were a pointer to + * a constant object (disallowing write access when dereferenced), while + * #SmartPointer# is a mutable pointer. */ -template +template class SmartPointer { - T* t; - public: + /** + * Standard constructor for null pointer. + */ + SmartPointer(); + /** * Constructor taking a normal pointer. + * If possible, i.e. if the pointer + * is not a null pointer, the constructor + * subscribes to the given object to + * lock it, i.e. to prevent its + * destruction before the end of its use. */ - SmartPointer(T* tt) : - t(tt) - { - if (t) - t->subscribe(); - } - - /** - * Standard constructor for null pointer. - */ - SmartPointer() : - t(0) - {} + SmartPointer (T *t); + + /** * Destructor, removing the subscription. */ - ~SmartPointer() - { - if (t) - t->unsubscribe(); - } - /** - * Assignment operator. Change of - * subscription is necessary. - */ - SmartPointer& operator=(T* tt) - { - if (t) - t->unsubscribe(); - t = tt; - if (tt) - tt->subscribe(); - return *this; - } + ~SmartPointer(); + + /** + * Assignment operator. Change of + * subscription is necessary. + */ + SmartPointer & operator= (T *tt); /** * Conversion to normal pointer. */ - operator T* () const - { - return t; - } - + operator T* () const; + /** * Dereferencing operator. */ - T& operator* () const - { - return *t; - } - + T& operator * () const; + /** * Dereferencing operator. */ - T* operator -> () const - { - return t; - } + T * operator -> () const; + + private: + /** + * Pointer to the object we want + * to subscribt to. + */ + const T* t; +}; + + + + + +/* --------------------------- Template functions ------------------------------*/ + + +template +SmartPointer::SmartPointer () : + t (0) +{}; + + + +template +SmartPointer::SmartPointer (const T *t) : + t (t) +{ + if (t) + t->subscribe(); +}; + + + +template +SmartPointer::~SmartPointer () { + if (t) + t->unsubscribe(); +}; + + + +template +SmartPointer & operator = (const T *tt) { + if (t) + t->unsubscribe(); + t = tt; + if (tt) + tt->subscribe(); + return *this; }; +template +inline +SmartPointer::operator T* () const { + return t; +}; + + + +template +inline +T & SmartPointer::operator * () const { + return *t; +}; + + + +template +inline +T * SmartPointer::operator -> () const { + return t; +}; + + + + + /*---------------------------- smartpointer.h ---------------------------*/ /* end of #ifndef __smartpointer_H */ #endif diff --git a/deal.II/base/include/base/smartreference.h b/deal.II/base/include/base/smartreference.h index 0ffcc819b2..d143fa85a0 100644 --- a/deal.II/base/include/base/smartreference.h +++ b/deal.II/base/include/base/smartreference.h @@ -12,7 +12,7 @@ * resolve the dot operator in a convenient manner. The use of * #SmartPointer# is recommended, instead. */ -template +template class SmartReference { T& t; diff --git a/deal.II/base/include/base/subscriptor.h b/deal.II/base/include/base/subscriptor.h index 34f780ba24..20aabf2be6 100644 --- a/deal.II/base/include/base/subscriptor.h +++ b/deal.II/base/include/base/subscriptor.h @@ -16,46 +16,27 @@ * This class, as a base class, allows to keep track of other objects * using a specific object. It is used, when an object, given to a * constructor by reference, is stored. Then, the original object may - * not be deleted before the dependent object is deleted. + * not be deleted before the dependent object is deleted. You can assert + * this constraint by letting the object passed be derived from this class + * and let the user #subscribe# to this object. The destructor the used + * object inherits from the #Subscriptor# class then will lead to an error + * when destruction is attempted while there are still subscriptions. */ class Subscriptor { - /** - * Store the number of objects which - * subscribed to this object. Initialally, - * this number is zero, and upon - * destruction it shall be zero again - * (i.e. all objects which subscribed - * should have unsubscribed again). - * - * The creator (and owner) of an object - * is not counted. - */ - mutable unsigned int counter; public: - /** - * Object may not be deleted, since - * it is used. - */ - DeclException0(InUse);//, unsigned, "Object is used " << counter << " times"); - DeclException0(NotUsed); - /** * Constructor setting the counter to zero. */ - Subscriptor() - : counter(0) - {} + Subscriptor(); + /** * Destructor, asserting that the counter * is zero. */ - ~Subscriptor() - { - Assert(counter==0, InUse()); - } - + ~Subscriptor(); + /** * Copy-constructor. * @@ -63,40 +44,65 @@ class Subscriptor * since references point to the * original object. */ - Subscriptor(const Subscriptor&) - : counter(0) - {} - + Subscriptor(const Subscriptor&); + /** * Assignment operator. * * This has to be handled with * care, too, because the counter - * has to remain the same. + * has to remain the same. It therefore + * does nothing more than returning + * #*this#. */ - Subscriptor& operator = (const Subscriptor&) - { - return *this; - } - + Subscriptor& operator = (const Subscriptor&); + /** * Subscribes a user of the object. */ - void subscribe () const - { - ++counter; - } - + void subscribe () const; + /** * Unsubscribes a user from the object. */ - void unsubscribe () const - { - Assert(counter>0, NotUsed()); - --counter; - } + void unsubscribe () const; + + /** + * Exception: + * Object may not be deleted, since + * it is used. + */ + DeclException0(InUse); + /** + * Exception: object should be used + * when #unsubscribe# is called. + */ + DeclException0(NotUsed); + + + private: + /** + * Store the number of objects which + * subscribed to this object. Initialally, + * this number is zero, and upon + * destruction it shall be zero again + * (i.e. all objects which subscribed + * should have unsubscribed again). + * + * The creator (and owner) of an object + * is not counted. + * + * We use the #mutable# keyword in order + * to allow subscription to constant + * objects also. + */ + mutable unsigned int counter; }; + + + + /*---------------------------- subscriptor.h ---------------------------*/ /* end of #ifndef __subscriptor_H */ #endif diff --git a/deal.II/base/source/subscriptor.cc b/deal.II/base/source/subscriptor.cc new file mode 100644 index 0000000000..65c8c15f25 --- /dev/null +++ b/deal.II/base/source/subscriptor.cc @@ -0,0 +1,40 @@ +/* $Id$ */ + +#include + + + +Subscriptor::Subscriptor () : + counter (0) +{}; + + + +Subscriptor::Subscriptor (const Subscriptor &) : + counter (0) +{}; + + + +Subscriptor::~Subscriptor () { + Assert (counter == 0, InUse()); +}; + + + +Subscriptor & Subscriptor::operator = (const Subscriptor &) { + return *this; +}; + + + +void Subscriptor::subscribe () const { + ++counter; +}; + + + +void Subscriptor::unsubscribe () const { + Assert (counter>0, NotUsed()); + --counter; +}; -- 2.39.5