NVIDIA Iray: Math API nvidia_logo_transpbg.gif Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
mi::base::Handle< Interface > Class Template Reference

Handle class template for interfaces, automatizing the lifetime control via reference counting. More...

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)
 Move constructor. More...
 
void swap (Self &other)
 Swap two interfaces. More...
 
Selfoperator= (const Self &other)
 Assignment operator, releases old interface and increments reference count of the new interface if interface is valid. More...
 
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= (Self &&other)
 Move assignment operator, releases old interface. 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. 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 & 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, which is the equivalent of a dynamic cast. More...
 
 operator bool_conversion_support () const
 Helper function for the conversion of a Handle<Interface> to a bool. More...
 

Friends

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

Detailed Description

template<class Interface>
class mi::base::Handle< Interface >

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* interface)
{
// do something with handle
}
mi::base::IInterface* interface = ...
foo( interface);
// do more things with interface

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 for an extended example (and for the same example without handle class).

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

Member Typedef Documentation

template<class Interface>
typedef bool(Handle::* mi::base::Handle< Interface >::bool_conversion_support)() const

Helper typedef.

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

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

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

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

Type of the underlying interface.

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

Mutable-pointer type to underlying interface.

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

Mutable-reference type to underlying interface.

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

Own type.

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

Type of the underlying interface.

Constructor & Destructor Documentation

template<class Interface>
mi::base::Handle< Interface >::Handle ( )
inline

Default constructor, initializes handle to hold an invalid interface.

template<class Interface>
mi::base::Handle< Interface >::Handle ( Interface *  ptr)
inlineexplicit

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.

template<class Interface>
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.

template<class Interface>
mi::base::Handle< Interface >::Handle ( const Self other)
inline

Copy constructor, increments reference count if interface is valid.

template<class Interface>
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.

template<class Interface>
mi::base::Handle< Interface >::Handle ( Self &&  other)
inline

Move constructor.

template<class Interface>
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 Function Documentation

template<class Interface>
Interface* mi::base::Handle< Interface >::get ( ) const
inline

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

template<class 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.

template<class Interface>
bool mi::base::Handle< Interface >::is_valid_interface ( ) const
inline

Returns true if the interface is valid.

template<class Interface>
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()) ...
template<class Interface>
Interface& mi::base::Handle< Interface >::operator* ( ) const
inline

The dereference operator accesses the interface.

Precondition
is_valid_interface().
template<class Interface>
Interface* mi::base::Handle< Interface >::operator-> ( ) const
inline

The arrow operator accesses the interface.

Precondition
is_valid_interface().
template<class 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 Interface>
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.

template<class Interface>
Self& mi::base::Handle< Interface >::operator= ( Self &&  other)
inline

Move assignment operator, releases old interface.

template<class Interface>
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.

template<class Interface>
void mi::base::Handle< Interface >::reset ( )
inline

Releases the current interface, decrementing the reference count.

template<class Interface>
void mi::base::Handle< Interface >::swap ( Self other)
inline

Swap two interfaces.

Friends And Related Function Documentation

template<class Interface>
bool operator!= ( const Handle< Interface > &  lhs,
const Interface *  rhs 
)
friend

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

template<class Interface>
bool operator!= ( const Interface *  lhs,
const Handle< Interface > &  rhs 
)
friend

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

template<class Interface>
bool operator== ( const Handle< Interface > &  lhs,
const Interface *  rhs 
)
friend

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

template<class Interface>
bool operator== ( const Interface *  lhs,
const Handle< Interface > &  rhs 
)
friend

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