Handle class template for interfaces, automatizing the lifetime control via reference counting. More...
#include <handle.h>
Public Types | |
typedef Handle<Interface> | Self |
Own type. More... | |
typedef Interface | Interface_type |
Type of the underlying interface. More... | |
typedef Interface | value_type |
Type of the underlying interface. More... | |
typedef Difference | difference_type |
Difference type (signed integral type to hold pointer differences). More... | |
typedef Interface * | pointer |
Mutable-pointer type to underlying interface. More... | |
typedef Interface & | reference |
Mutable-reference type to underlying interface. More... | |
typedef bool(Handle::* | bool_conversion_support) () const |
Helper typedef. More... | |
Public Member Functions | |
Handle () | |
Default constructor, initializes handle to hold an invalid interface. More... | |
Handle (Interface *ptr) | |
Constructor from interface pointer, takes ownership of interface. More... | |
Handle (Interface *ptr, Dup_interface) | |
Constructor from interface pointer, does not take ownership of interface but duplicates it. More... | |
Handle (const Self &other) | |
Copy constructor, increments reference count if interface is valid. More... | |
template<class Interface2> | |
Handle (const Handle<Interface2> &other) | |
Copy constructor template which allows the construction from assignment compatible interface pointers, increments reference count if interface is valid. More... | |
Handle (Self &&other) noexcept | |
Move constructor. More... | |
template<class Interface2> | |
Handle (Handle<Interface2> &&other) noexcept | |
Converting move constructor. More... | |
void | swap (Self &other) |
Swap two interfaces. More... | |
Self & | operator= (const Self &other) |
Assignment operator, releases old interface and increments reference count of the new interface if interface is valid. More... | |
template<class Interface2> | |
Self & | operator= (const Handle<Interface2> &other) |
Assignment operator template, releases old interface and increments reference count of the new interface if interface is valid. More... | |
Self & | operator= (Self &&other) noexcept |
Move assignment operator, releases old interface. More... | |
template<class Interface2> | |
Self & | operator= (Handle<Interface2> &&other) noexcept |
Converting move assignment operator, releases old interface. More... | |
Self & | operator= (Interface *ptr) |
Assignment operator from interface pointer, releases old interface and assigns new interface ptr , takes ownership of interface. More... | |
void | reset () |
Releases the current interface, decrementing the reference count. More... | |
~Handle () | |
Destructor, releases the interface if it is valid, which decrements the reference count, and triggers thus the deletion of the interface implementation once the reference count reaches zero. More... | |
bool | is_valid_interface () const |
Returns true if the interface is valid. More... | |
Interface * | get () const |
Access to the interface. Returns 0 for an invalid interface. More... | |
Interface * | extract () |
Extracts the interface and releases the handle. More... | |
Interface & | operator* () const |
The dereference operator accesses the interface. More... | |
Interface * | operator-> () const |
The arrow operator accesses the interface. More... | |
template<class New_interface> | |
Handle<New_interface> | get_interface () const |
Returns a new handle for a possibly different interface type, similar to a dynamic cast, but not necessarily restricted to derived interfaces, but also for otherwise related interfaces. More... | |
operator bool_conversion_support () const | |
Helper function for the conversion of a Handle<Interface> to a bool. More... | |
Handle class template for interfaces, automatizing the lifetime control via reference counting.
The Handle class is smart-pointer class that handles the reference counting of interface classes automatically. A handle stores internally a pointer to the underlying interface class.
Template parameter:
Interface:
an interface class, i.e., either the mi::base::IInterface class itself or a class derived from it.I
and Handle<I> for a mutable pointer to an interface class I
.The Handle class has two constructors which differ in the way they handle ownership of the interface pointer they are constructed from (actually, there is a third constructor, the default constructor, which constructs an invalid handle). In the first form mi::base::Handle<I>(I*) the Handle instance takes ownership of the interface. In the second form mi::base::Handle<I>(I*,Dup_interface) it does not take ownership of the interface, but duplicates it.
The following two examples, based on the neuraylib API, illustrate the use of both constructors. The first example demonstrates the prevailing use case where you want to locally store the interface pointer returned from an API function for subsequent usage. In this case you should use the first form of the constructor which takes ownership of the interface.
On the other hand, assume that you want to store a pointer to an interface whose lifetime you do not control. This typically happens when a pointer is passed as parameter to a function. By convention such pointers are owned by the function caller.
If you had not used the second form of the handle constructor in this example, the handle destructor would have decremented the reference counter of interface
to 0 at the end of foo(). Therefore, the corresponding interface would have been destroyed and the interface
pointer would be invalid after the foo() call.
In contrast, the second form of the handle constructor does not take ownership of the interface
pointer, but increments the reference count once more. Consequently, when the handle is destroyed, the reference count does not drop to 0.
Note that this use case often shows up when you store a pointer passed in via a member function as a class member.
See also Handle class for an extended example (and Reference counting for the same example without handle class).
#include <mi/base/handle.h>