In last two items I talked about managing resources using RAII objects. Now here comes the practical part. Often we will encounter a situation that a API only accept raw resource instead of RAII objects. For example:
1 | // You have a shared pointer |
In this situation, you need the RAII class return a raw pointer of the resource. And there are commonly two way to do that.
- Explicitly provide method to return the raw resource. This is how shared_ptr handles this situation. It provide get() method to return the raw resource it contains. In addition, it also overload operator-> and operator*. I prefer this way cause it’s clear and safe. But some people don’t like this explicit conversion and they will abandon to use this RAII class which, in turn, would increase the chances of leaking memory. In order to satisfy these people, we have the second way to accomplish that.
- **Implicitly convert RAII objects to raw resource objects.**How to do this? Let’s see an example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Font
{
public:
explicit Font(FontHandle fh):
f(fh)
{}
~Font(){releaseFont(f);}
// explicitly convert Font to FontHandle
operator FontHandle() const
{return f;}
....
private:
FontHandle f;
};
We overload operator FontHandle to implicit convert Font to FontHandle. This provide you the ability to omit .get() no matter the API accept Font or FontHandle. But this method has a downside. The risk is unintentional type conversion. For example:
1 | Font f1(getFont()); |
In this way, resource may leak due to the implicitly conversion. That’s why I prefer the first approach cause it’s safe and clear.