Item 15 - Provide access to raw resources in resource managing classes.
Item 13 introduces the idea of using smart pointers like auto_ptr
or shared_ptr
to hold the result of a call to a factory function like createInvestment
:
std::shared_ptr<Investment> pInv (createInvestment());
Suppose that a function you'd like to use when working with Investment
objects is this:
int daysHeld(const Investment* pi); // return number of days investment has been held
You'd like to call it like this
int days = daysHeld(pInv); // error!
but the code won't compile: daysHeld
wants a raw Investment*
pointer, but you're passing an object of type shared_ptr<Investment>
.
You need a way to convert an object of the RAII class (in this case shared_ptr
) into the raw resource it contains (e.g., the underlying Investment*
). There are two general ways to do it: explicit conversion and implicit conversion.
shared_ptr
and auto_ptr
both offer a get member function to perform an explicit conversion, i.e., to return (a copy of) the raw pointer inside the smart pointer object:
int days = daysHeld(pInv.get()); // fine, passes the raw pointer in pInv to daysHeld
Like virtually all smart pointer classes shared_ptr
and auto_ptr
also overload the pointer dereferencing operators (->
and *
), and this allows implicit conversion to the underlying raw pointers:
class Investment { // root class for a hierarchy of investment types
public:
bool isTaxFree() const;
...
};
Investment* createInvestment(); // factory function
shared_ptr<Investment> pi1(createInvestment()); // shared_ptr manage a resource
bool taxable1 = !(pi1->isTaxFree()); // access resource via operator->
...
auto_ptr<Investment> pi2(createInvestment()): // auto_ptr manage a resource
bool taxable2 = !((*pi2).isTaxFree()); // access resource via operator*
Things to Remember
- APIs often require access to raw resource, so each RAII class should offer a way to get to the resource it manages.
- Access may be via explicit conversion or implicit conversion. In general, explicit conversion is safer, but implicit conversion is more convenient for clients.