neuray API Programmer's Manual

mi::base::Handle< Interface> Template Class Reference

[Interface Framework Technology]

template< class Interface>

class mi::base::Handle< Interface>

Description

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.

Note:

The Handle class is const correct: Use Handle< const I > for a const pointer to an interface class 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.

mi::base::Handle< mi::neuraylib::INeuray> neuray( mi_neuray_factory());
        neuray->start( true);

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.

‎        void foo (mi::base::IInterface* iinterface) {
            mi::base::Handle< mi::base::IInterface> handle( iinterface, mi::base::DUP_INTERFACE);
            // do something with handle
        }

        mi::base::IInterface* iinterface = ...
        foo( iinterface);
        // do more things with iinterface

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 iinterface to 0 at the end of foo(). Therefore, the corresponding interface would have been destroyed and the iinterface pointer would be invalid after the foo() call.

In contrast, the second form of the handle constructor does not take ownership of the iinterface 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.

Include File:

#include <mi/base/handle.h>

See also:

make_handle() and make_handle_dup() for creating a typed handle from a typed interface pointer

Public Typedefs

typedef Interface  Interface_type
Type of the underlying interface.
typedef Handle< Interface> Self
Own type.
typedef bool(Handle::*  bool_conversion_support
Helper typedef. More...
typedef Difference difference_type
Difference type (signed integral type to hold pointer differences).
typedef Interface *  pointer
Mutable-pointer type to underlying interface.
typedef Interface &  reference
Mutable-reference type to underlying interface.
typedef Interface  value_type
Type of the underlying interface.

Public Constructors

 Handle()
Default constructor, initializes handle to hold an invalid interface.
 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.
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...

Public Destructors

 ~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.

Public Member Functions

Interface* get() const
Access to the interface. Returns 0 for an invalid interface.
template< class New_interface> Handle < New_interface > get_interface() const
Returns a new handle for a possibly different interface type, which is the equivalent of a dynamic cast. More...
bool  is_valid_interface() const
Returns true if the interface is valid.
 operator bool_conversion_support() const
Helper function for the conversion of a Handle<Interface> to a bool. More...
Interface& operator*() const
The dereference operator accesses the interface. More...
Interface* operator->() const
The arrow operator accesses the interface. More...
Selfoperator=( const Self& other)
Assignment operator, releases old interface and increments reference count of the new interface if interface is valid.
template< class Interface2>Selfoperator=( const Handle < Interface2 >& other)
Assignment operator template, releases old interface and increments reference count of the new interface if interface is valid. More...
Selfoperator=( 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.
void swap( Self& other)
Swap two interfaces.

Friend Functions

bool operator!=( const Handle < Interface >& lhs, const Interface* rhs)
Returns true if the underlying interface pointer of lhs is not equal to rhs.
bool operator!=( const Interface* lhs, const Handle < Interface >& rhs)
Returns true if lhs is not equal to the underlying interface pointer of rhs.
bool operator==( const Handle < Interface >& lhs, const Interface* rhs)
Returns true if the underlying interface pointer of lhs is equal to rhs.
bool operator==( const Interface* lhs, const Handle < Interface >& rhs)
Returns true if lhs is equal to the underlying interface pointer of rhs.

Typedefs

typedef Interface mi::base::Handle< Interface>::Interface_type

Type of the underlying interface.

typedef Handle< Interface> mi::base::Handle< Interface>::Self

Own type.

typedef bool(Handle::* mi::base::Handle< Interface>::bool_conversion_support

Helper typedef. This typedef represent the type of is_valid_interface() used by the bool_conversion_support() operator.

typedef Difference mi::base::Handle< Interface>::difference_type

Difference type (signed integral type to hold pointer differences).

typedef Interface * mi::base::Handle< Interface>::pointer

Mutable-pointer type to underlying interface.

typedef Interface & mi::base::Handle< Interface>::reference

Mutable-reference type to underlying interface.

typedef Interface mi::base::Handle< Interface>::value_type

Type of the underlying interface.

Constructors

mi::base::Handle< Interface>::Handle() [inline]

Default constructor, initializes handle to hold an invalid interface.

mi::base::Handle< Interface>::Handle( Interface* ptr) [inline, explicit]

Constructor from interface pointer, takes ownership of interface. The constructor does not increment the reference count of ptr assuming it is already set properly, e.g., by a corresponding get_interface() call. It therefore takes over the ownership of the interface pointer.

mi::base::Handle< Interface>::Handle( Interface* ptr, Dup_interface) [inline]

Constructor from interface pointer, does not take ownership of interface but duplicates it. The constructor increments the reference count of ptr so that it does not influence the interface when it decrements the reference count later on. You can use this constructor for example to hold interfaces that are passed into functions as parameters because by convention they are owned by the function caller. You can pass the constant DUP_INTERFACE as the second argument.

mi::base::Handle< Interface>::Handle( const Self& other) [inline]

Copy constructor, increments reference count if interface is valid.

template< class Interface2>

mi::base::Handle< Interface>::Handle( const Handle < Interface2 >& other) [inline]

Copy constructor template which allows the construction from assignment compatible interface pointers, increments reference count if interface is valid. This constructor allows specifically the construction of a Handle< const I > from a Handle< I > value, which corresponds to the assignment of a mutable pointer to a const pointer. In addition, promotion of derived interfaces to base interfaces is allowed.

Destructors

mi::base::Handle< Interface>::~Handle() [inline]

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.

Member Functions

Interface* mi::base::Handle< Interface>::get() const [inline]

Access to the interface. Returns 0 for an invalid interface.

template< class New_interface>

Handle < New_interface > mi::base::Handle< Interface>::get_interface() const [inline]

Returns a new handle for a possibly different interface type, which is the equivalent of a dynamic cast. Returns a handle with an invalid interface if the requested interface type is not supported by the underlying interface implementation or if this interface is itself already invalid.

bool mi::base::Handle< Interface>::is_valid_interface() const [inline]

Returns true if the interface is valid.

mi::base::Handle< Interface>::operator bool_conversion_support() const [inline]

Helper function for the conversion of a Handle<Interface> to a bool. This helper function allows to write

‎     Handle<T> h (...);
     if (h) ...
instead of
‎     Handle<T> h (...);
     if (h.is_valid_interface()) ...
Interface& mi::base::Handle< Interface>::operator*() const [inline]

The dereference operator accesses the interface.

Precondition:

is_valid_interface().

Interface* mi::base::Handle< Interface>::operator->() const [inline]

The arrow operator accesses the interface.

Precondition:

is_valid_interface().

Self& mi::base::Handle< Interface>::operator=( const Self& other) [inline]

Assignment operator, releases old interface and increments reference count of the new interface if interface is valid.

template< class Interface2>

Self& mi::base::Handle< Interface>::operator=( const Handle < Interface2 >& other) [inline]

Assignment operator template, releases old interface and increments reference count of the new interface if interface is valid. This assignment operator allows specifically the assignment of a Handle< I > to a Handle< const I > value, which corresponds to the assignment of a mutable pointer to a const pointer. In addition, promotion of derived interfaces to base interfaces is allowed.

Self& mi::base::Handle< Interface>::operator=( Interface* ptr) [inline]

Assignment operator from interface pointer, releases old interface and assigns new interface ptr, takes ownership of interface. Does not increment reference count of ptr assuming it is already set properly, e.g., by a corresponding get_interface() call.

void mi::base::Handle< Interface>::reset() [inline]

Releases the current interface, decrementing the reference count.

void mi::base::Handle< Interface>::swap( Self& other) [inline]

Swap two interfaces.

Friend Functions

bool operator!=( const Handle < Interface >& lhs, const Interface* rhs) [friend, inline]

Returns true if the underlying interface pointer of lhs is not equal to rhs.

bool operator!=( const Interface* lhs, const Handle < Interface >& rhs) [friend, inline]

Returns true if lhs is not equal to the underlying interface pointer of rhs.

bool operator==( const Handle < Interface >& lhs, const Interface* rhs) [friend, inline]

Returns true if the underlying interface pointer of lhs is equal to rhs.

bool operator==( const Interface* lhs, const Handle < Interface >& rhs) [friend, inline]

Returns true if lhs is equal to the underlying interface pointer of rhs.