* }
* delete p;
* \end{verbatim}
+ *
+ * Note that a smart pointer can handle #const#ness of an object, i.e.
+ * a #SmartPointer<const ABC># really behaves as if it were a pointer to
+ * a constant object (disallowing write access when dereferenced), while
+ * #SmartPointer<ABC># is a mutable pointer.
*/
-template<class T>
+template<typename T>
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<T>& operator=(T* tt)
- {
- if (t)
- t->unsubscribe();
- t = tt;
- if (tt)
- tt->subscribe();
- return *this;
- }
+ ~SmartPointer();
+
+ /**
+ * Assignment operator. Change of
+ * subscription is necessary.
+ */
+ SmartPointer<T> & 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 <typename T>
+SmartPointer<T>::SmartPointer () :
+ t (0)
+{};
+
+
+
+template <typename T>
+SmartPointer<T>::SmartPointer (const T *t) :
+ t (t)
+{
+ if (t)
+ t->subscribe();
+};
+
+
+
+template <typename T>
+SmartPointer<T>::~SmartPointer () {
+ if (t)
+ t->unsubscribe();
+};
+
+
+
+template <typename T>
+SmartPointer<T> & operator = (const T *tt) {
+ if (t)
+ t->unsubscribe();
+ t = tt;
+ if (tt)
+ tt->subscribe();
+ return *this;
};
+template <typename T>
+inline
+SmartPointer<T>::operator T* () const {
+ return t;
+};
+
+
+
+template <typename T>
+inline
+T & SmartPointer<T>::operator * () const {
+ return *t;
+};
+
+
+
+template <typename T>
+inline
+T * SmartPointer<T>::operator -> () const {
+ return t;
+};
+
+
+
+
+
/*---------------------------- smartpointer.h ---------------------------*/
/* end of #ifndef __smartpointer_H */
#endif
* 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.
*
* 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