Each RAII class should offer a way to get at the resource it manages.
From time to time, some APIs require access to raw resources, so it is a good habit to design the resource-managing classes in such a way that it provides access to raw resources. For example, suppose there’s a function we’d like to use with Investment
objects, which is managed by smart pointer:
|
|
Since dayHeld
wants a raw Investment*
pointer, if passing an object of type tr1::shared_ptr<Investment>
, the code won’t compile:
|
|
We need to find a way to get the access to the raw resources, and generally there are two ways:
- Implicit conversion (convenient for clients)
- Explicit conversion (generally preferred)
Implicit conversion
Pointer dereferencing operators (operator->
and operator*
) are implicit conversion to the underlying raw pointers, which is virtually provided by all smart pointer classes. Suppose there’s a member function bool isTaxFree()
inside the class Investment
, and we can access the member function like this:
|
|
When it is necessary to get at the raw resource inside an RAII object, another way of conversion is through an implicit conversion function. Consider following RAII class for fonts:
|
|
This makes calling into the following C API easy and natural:
|
|
However, the downsize is that implicit conversions increase the chance of errors - a FontHandle
may be created when a Font
is really intended:
|
|
Explicit conversion
In order to avoid unintended implicit conversion, an explicit conversion function like get
is a preferable path. We can exchange the implicit convertion function to following explicit one:
|
|
Both explicit conversion and implicit conversion make sense, and the preference depends on the specific task and the circumstances in which the RAII class performs, as long as one adheres to item 18’s advice: to make interfaces easy to use correctly and hard to use incorrectly.