From 8e78168fa4c72e0be17f537dff7a4c1fddb1e63a Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Fri, 18 Oct 2024 16:40:11 -0600 Subject: [PATCH] Better document the EnableObserverPointer class. --- .../deal.II/base/enable_observer_pointer.h | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/include/deal.II/base/enable_observer_pointer.h b/include/deal.II/base/enable_observer_pointer.h index f8cbd4a9e3..1fffaa2c6c 100644 --- a/include/deal.II/base/enable_observer_pointer.h +++ b/include/deal.II/base/enable_observer_pointer.h @@ -30,29 +30,36 @@ 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 const char 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 typeid(x).name() where - * x 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` object that points objects of type `X` (where `X` is + * derived from EnableObserverPointer). When you write + * @code + * ObserverPointer 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 */ -- 2.39.5