DEAL_II_NAMESPACE_OPEN
/**
- * Handling of subscriptions.
+ * This class supports the functioning of the ObserverPointer class.
*
- * This class, as a base class, allows to keep track of other objects using a
- * specific object. It is used to avoid that pointers that point to an object of
- * a class derived from EnableObserverPointer are referenced after
- * that object has been invalidated. Here, invalidation is assumed to happen
- * when the object is moved from or destroyed. The mechanism works as follows:
- * The member function subscribe() accepts a pointer to a boolean that is
- * modified on invalidation. The object that owns this pointer (usually an
- * object of class type ObserverPointer) is then expected to check the state of
- * the boolean before trying to access this class.
+ * Used as a base class, this class allows the ObserverPointer class to register
+ * with an object that it is observing that object. As a consequence, the object
+ * can report an error when its destructor is called if there are still
+ * ObserverPointers pointing to it, since destroying the object would lead to
+ * dangling pointers that point to memory that's no longer valid.
*
- * The utility of this class is even enhanced by providing identifying strings
- * to the functions subscribe() and unsubscribe(). These strings are represented
- * as <code>const char</code> pointers since the underlying buffer comes from
- * (and is managed by) the run-time type information system: more exactly, these
- * pointers are the result the function call <code>typeid(x).name()</code> where
- * <code>x</code> is some object. Therefore, the pointers provided to
- * subscribe() and to unsubscribe() must be the same. Strings with equal
- * contents will not be recognized to be the same. The handling in
- * ObserverPointer will take care of this.
- * The current subscribers to this class can be obtained by calling
- * list_subscribers().
+ * In actual practice, the mechanism works as follows: Assume you have an
+ * `ObserverPointer<X>` object that points objects of type `X` (where `X` is
+ * derived from EnableObserverPointer). When you write
+ * @code
+ * ObserverPointer<X> ptr;
+ * X object;
+ * ptr = &x;
+ * @endcode
+ * then `ObserverPointer::operator=()` called in the last line of the code above
+ * will call the EnableObserverPointer::subscribe() function (of the class
+ * documented here) with arguments that allow both
+ * sides to track each other. If `object` goes out of scope while `ptr` is still
+ * pointing to it, this would create a dangling pointer, and the destructor of
+ * `X` (i.e., actually the destructor of the EnableObserverPointer base class of
+ * `X`) will abort the program with an error.
+ *
+ * In practice, when such an error happens, it is often difficult to tell
+ * *which* pointer is still pointing to the `object` that is being destroyed. To
+ * this end, ObserverPointer can also pass a string to the subscribe() member
+ * function that identifies which observer is still alive. This string is passed
+ * to the ObserverPointer object upon construction and is user-defined so that
+ * code developed can give names to their observer pointers.
*
* @ingroup memory
*/